2009-07-23 133 views
1

我经常遇到以下情况:我在表中有一些数据(嵌套数组),并且需要循环其中的所有项。第一个/最后一个项目和项目组的循环设计?

要求:

  1. 第一项应该被识别和分开处理。
  2. 最后一项应分开标识和处理。
  3. 如果类似的物品被分类,它们应该被标识为第一组和最后一组物品。 (在这种情况下按性别分类/分组)
  4. 应给出小组项目的小计和所有项目的总数。

DATA: 动漫角色与名字,姓氏,tvshow,性别 假设按性别进行排序,姓氏。

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

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

OUTPUT:

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 

回答

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 
+0

令人印象深刻的设计。 – capfu 2009-07-23 09:53:27

1

对于利益着想,我决定去看看这个看起来像Groovy,它是一种真正的闭包语言,元编程语言和一些很酷的列表操作符。下面的代码给出或多或少的相同结果,虽然它要求列表在内存中,并不是特别有效。然而,它的可读性要高得多,而且...... groovier。

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()) 
} 
+0

我最喜欢的是(如果我正确阅读的话)是,您不相信要排序的字符,并明确地按照GENDER排序(尽管忽略LASTNAME)。 – capfu 2009-07-24 09:20:13

相关问题