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

时间:2009-07-23 01:41:38

标签: loops

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

要求:

  1. 应分别识别和处理第一项。
  2. 应识别最后一项并单独处理。
  3. 如果对类似的项目进行排序,则应在组中标识它们,并标识第一个和最后一个组项目。 (在这种情况下按性别排序/分组)
  4. 应该给出小组项目的小计和所有项目的总数。
  5. 数据: 带有名字,姓氏,电视节目,性别的漫画人物 假设按性别命名,姓氏。

    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 个答案:

答案 0 :(得分:1)

我选择了世界上最冗长的语言(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

答案 1 :(得分:1)

为了感兴趣,我决定在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())
}