代码之家  ›  专栏  ›  技术社区  ›  capfu

第一个/最后一个项目和项目组的循环设计?

  •  1
  • capfu  · 技术社区  · 17 年前

    我经常遇到以下情况:表中有一些数据(嵌套数组),需要循环其中的所有项。

    要求:

    1. 最后一项应单独确定和处理。
    2. 应给出分组项目的小计和所有项目的总计。

    数据: 具有名字、姓氏、电视节目、性别的喜剧角色 假设按性别、姓氏排序。

    Turanga|Leela|Futurama|Female
    Marge|Simpson|The Simpsons|Female
    Eric|Cartman|South Park|Male
    Peter|Griffin|Family Guy|Male
    Homer|Simpson|The Simpsons|Male
    

    问题: 如何编写一个循环(欢迎使用任何语言!),以生成以下输出? 缩进并不重要。

    输出:

    First Entry: Turanga Leele (Futurama)
    --
    First Female: Turanga Leela (Futurama)
    Last Female : Marge Simpson (The Simpsons)
    --
    Total Females: 2
    --
    First Male: Eric Cartman (South Park)
                Peter Griffin (Family Guy)
    Last Male : Homer Simpson (The Simpsons)
    --
    Total Males: 3
    --
    Last Entry: Homer Simpson (The Simpsons)
    --
    Total Entries: 5
    
    2 回复  |  直到 17 年前
        1
  •  1
  •   Dean Povey    17 年前

    我选择了世界上最冗长的语言(Java)来实现这一点,但这应该可以满足您的需要。它只需要一次传球,但需要一排向前看。它还需要至少两行输入,尽管它相对容易适应任意数量的行:

        import java.util.Arrays;
        import java.util.HashMap;
        import java.util.Iterator;
        import java.util.List;
        import java.util.Map;
    
        import static java.lang.System.out;
    
        public class Loop {
            static enum Col { FIRST_NAME, LAST_NAME, TV_SHOW, GENDER }
    
        private static final List<String[]> characters = Arrays.asList(
                new String[] {"Turanga", "Leela", "Futurama", "Female"},
                new String[] {"Marge", "Simpson", "The Simpsons", "Female"},
                new String[] {"Eric", "Cartman", "South Park", "Male"},
                new String[] {"Peter", "Griffin", "Family Guy", "Male"},
                new String[] {"Homer", "Simpson", "The Simpsons", "Male"});    
    
        public static void summarize(List<String[]> character, Col groupBy) {
            assert character.size() > 1;        
            int total = 0;
            Iterator<String[]> i = characters.iterator();
            String[] row = next(i);
            String[] peek = next(i);
            String group;
            out.print("First Entry:" + format(row));        
            Map<String, Integer> subTotals = new HashMap<String, Integer>();
            do {
                group = col(row, groupBy);
                out.print("First " + group + ":");            
                subTotals.put(group, 0);
                do {
                    out.print(format(row));
                    total = incrementTotals(total, group, subTotals);
                    row = peek;
                    peek = next(i);
                } while (peek != null && col(peek, groupBy).equals(group));
                total = incrementTotals(total, group, subTotals);
                out.print("Last " + group + ":" + format(row));
                out.println("--");
                out.println("Total " + group + "s:" + subTotals.get(group));
                out.println("--");
                if (peek == null) break;
                row = peek;
                peek = next(i);            
            } while(true);
            out.print("Last Entry:" + format(row));
            out.println("--");
            out.println("Total Entries:" + total);        
        }
    
    
        private static String[] next(Iterator<String[]> i) {
            if (i.hasNext())
                return i.next();
            return null;
        }
    
    
        private static int incrementTotals(int total, String group,
                Map<String, Integer> subTotals) {
            total++;
            subTotals.put(group, subTotals.get(group) + 1);
            return total;
        }
    
        private static String format(String[] row) {
            return col(row, Col.FIRST_NAME) + " " + col(row, Col.LAST_NAME)
                + "(" + col(row, Col.TV_SHOW) + ")\n";
        }
    
        private static String col(String[] row, Col col) {
            return row[col.ordinal()];
        }
    
        public static void main(String args[]) {
            summarize(characters, Col.GENDER);
        }
    
    }
    

    First Entry:Turanga Leela(Futurama)
    First Female:Turanga Leela(Futurama)
    Last Female:Marge Simpson(The Simpsons)
    --
    Total Females:2
    --
    First Male:Eric Cartman(South Park)
    Peter Griffin(Family Guy)
    Last Male:Homer Simpson(The Simpsons)
    --
    Total Males:3
    --
    Last Entry:Homer Simpson(The Simpsons)
    --
    Total Entries:5
    
        2
  •  1
  •   Dean Povey    17 年前

    出于兴趣,我决定看看Groovy是一种真正的语言,它包含闭包、元编程和一些很酷的列表操作符。下面的代码给出了大致相同的结果,尽管它要求列表在内存中,并且不是特别有效。然而,它更具可读性,而且。。非常棒。

    enum Col { FIRST_NAME, LAST_NAME, TV_SHOW, GENDER }
    def characters = [
            [ "Turanga", "Leela", "Futurama", "Female" ],
            [ "Marge", "Simpson", "The Simpsons", "Female" ],
            [ "Eric", "Cartman", "South Park", "Male" ],
            [ "Peter", "Griffin", "Family Guy", "Male" ],
            [ "Homer", "Simpson", "The Simpsons", "Male" ]
    ]
    
    // Use Groovy Metaprogramming to add some methods to the List class
    List.metaClass.first = { cl -> if (delegate.size > 0) cl(delegate[0]) }
    List.metaClass.middle = { cl -> 
        if (delegate.size > 2) 1..delegate.size-2.each { i -> cl(delegate[i]) }
    }
    List.metaClass.last = {  cl -> if (delegate.size > 1) return cl(delegate[delegate.size-1]) }
    
    def format(row) { 
        return row[Col.FIRST_NAME.ordinal()] + " " +
               row[Col.LAST_NAME.ordinal()] + " (" +
               row[Col.TV_SHOW.ordinal()] + ")"
    }
    
    // Loop through and summarize the Characters
    characters.first { row ->
        println("First Entry: ${format(row)}")
    }
    def groups = characters.groupBy { row -> row[Col.GENDER.ordinal()] }
    groups.each { groupType, group ->    
        group.first { row -> println("First ${groupType}: ${format(row)}") }
        group.middle { row -> println(format(row)) }
        group.last { row -> println("Last ${groupType}: ${format(row)}") }
        println("--")
        println("Total ${groupType}s: ${group.size}")
        println("--")
    }
    characters.last { row ->
        println("Last Entry : ${format(row)}")
        println("--")
        println("Total Items: " + characters.size())
    }