0

我在寻找最有效的解决方案时遇到了一个小问题。我有一个学生编号,例如 10 。其中一些 id 彼此是相对的(兄弟姐妹)。对于那些是兄弟姐妹的人来说,只留下一个来识别,不管哪个,第一个就可以了。

例如,学生证

  • 原来的

    1、2、3、4、5、6、7、8、9、10

1, 2, 3一个家庭兄弟姐妹在哪里,8, 9另一个在哪里。最后我应该有:

  • 预期的

    1、4、5、6、7、8、10 _ _ _

我是通过循环来做的。


更新:

我只是停下来实施它,因为它变得越来越大。这是我脑海中的大图。我只是逐行收集每个给定 id 的所有兄弟 id,然后我将逐个迭代。但就像我说的那样,这是在浪费时间。

  • 代码(概念上)

    static string Trimsiblings(string ppl) {
        string[] pids=ppl.Split(',');
        Stack<string> personid=new Stack<string>();
    
        foreach(string pid in pids) {
            // access database and check for all sibling 
            // is for each individual pid 
            // such as in example above 
            // row 1: field 1=1, field2=2, field3=3 
            // row 2: field 1=8, field2=9 
    
            query = Select..where ..id = pid; // this line is pesudo code
    
            for(int i=0; i<query.Length; i++) {
                foreach(string pid in pids) {
                    if(query.field1==pid) {
                        personid.Push(pid);
    
                    }
                }
            }
        }
    }
    
4

2 回答 2

2

对于有效的代码,必须注意每个兄弟家庭的一个成员(例如,第一个)是不相关的,因为它将保留在输出中。也就是说,我们只需要

  1. 创建一个不能出现在输出中的项目列表
  2. 实际上删除它们

当然,这仅在每个兄弟实际上都出现在原始 id 列表中的假设下才有效。

在代码中:

int[] ids = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int families = new int[2][] {
    new int [] {1, 2, 3},
    new int [] {8, 9}
};
var itemsToOmit = siblings.
    Select(family => family.Skip(1)).
    Aggregate((family1, family2) => family1.Concat(family2));
var cleanedIds = ids.Except(itemsToOmit);

编辑:既然你提到你对语法不太熟悉,我会做一些进一步的解释

  • 我使用的表达式是属于System.LINQ命名空间的扩展方法
  • Select方法将一个序列转换为另一个序列。由于families序列的序列family将是同一家庭中的兄弟姐妹序列(即,1, 2, 38, 9这种特殊情况下)
  • Skip方法跳过序列中的许多元素。在这里,我决定总是跳过第一个元素(原因见上文)
  • Aggregate方法将序列的元素组合成单个元素。在这里,所有兄弟姐妹的家庭只是相互连接(除了每个家庭的第一个兄弟姐妹,已通过 Skip 省略)
  • except方法返回序列中不在作为参数给出的序列中的所有元素。

我希望这能澄清一些事情。

于 2013-03-19T05:28:18.343 回答
2

方法如下

public static String Trimsiblings(String ppl) {
    var table=GetSiblingTable();
    var pids=ppl.Split(',');

    return
        String.Join(", ", (
            from id in pids.Select(x => int.Parse(x))
            where (
                from row in table.AsEnumerable()
                select
                    from DataColumn column in table.Columns
                    let data=row[column.ColumnName]
                    where DBNull.Value!=data
                    select int.Parse((String)data)
                ).All(x => false==x.Contains(id)||x.First()==id)
            select id.ToString()).ToArray()
            );
}

// emulation of getting table from database
public static DataTable GetSiblingTable() {
    var dt=new DataTable();

    // define field1, ..., fieldn
    for(int n=3, i=1+n; i-->1; dt.Columns.Add("field"+i))
        ;

    dt.Rows.Add(new object[] { 1, 2, 3 });
    dt.Rows.Add(new object[] { 8, 9 });
    return dt;
}

public static void TestMethod() {
    Console.WriteLine("{0}", Trimsiblings("1, 2, 3, 4, 5, 6, 7, 8, 9, 10"));
}

评论以询问原因(如果需要)。

于 2013-03-19T07:55:23.470 回答