比较列表中的元素并创建一个新元素

时间:2015-09-03 13:24:38

标签: c#

我有一个用户名单:

List<UserEntry> list1 = new List<UserEntry>();
list1.Add(new UserEntry { login = "1", requestorList = new List<string>() { "1", "2", "3" } });
        list1.Add(new UserEntry { login = "2", requestorList = new List<string>() { "1", "4", "3" } });
        list1.Add(new UserEntry { login = "3", requestorList = new List<string>() { "1", "2", "3" } });

我想找到具有相同requestorList的元素,并将它们分组到第二个List中。在上面的例子中,第一个和第三个元素有1,2,3。

我尝试过这个并不起作用:

for (int i = 0; i < list1.Count; i++)
        {
            var kar = list1.ElementAt(i);
            for (int j = 0; j < list1.Count; j++)
            {
            if(kar.requestorList.Equals(list1.ElementAt(j).requestorList))
                {
                    list2.Add(kar);
                }
            }
        }

编辑:secoond列表应该只有2个元素,因为第一个和第三个元素具有相同的请求列表

3 个答案:

答案 0 :(得分:1)

如果你想获得你想要的名单,可以这样做:

首先,您需要添加第二个if,如下所示:

if(list1.ElementAt(i).Equals(list1.ElementAt(j))){
    continue;
}

为了跳过将元素与自身进行比较的情况。

此外,如果您不想复制,请使用此而不是仅执行list2.Add(kar);

if(!list2.Contains(kar)){

    list2.Add(kar);
}

编辑:如果我没有弄乱,完整的代码看起来应该是这样的:

for (int i = 0; i < list1.Count; i++)
        {
            var kar = list1.ElementAt(i);
            for (int j = 0; j < list1.Count; j++)
            {
            if(kar.requestorList.SequenceEqual(list1.ElementAt(j).requestorList))
                {
                     if(list1.ElementAt(i).Equals(list1.ElementAt(j))){
                          continue;
                     }

                     if(!list2.Contains(kar)){

                         list2.Add(kar);
                     }
                }
            }
        }

答案 1 :(得分:1)

这是你的代码略有差异

   for (int i = 0; i < list1.Count; i++)
        {
            var kar = list1.ElementAt(i);
            for (int j = i+1; j < list1.Count; j++)
            {
                if (Enumerable.SequenceEqual(kar.requestorList.OrderBy(t => t), list1.ElementAt(j).requestorList.OrderBy(t => t)))
                {
                    list2.Add(kar);
                    list2.Add(list1.ElementAt(j));
                }
            }
        }

答案 2 :(得分:0)

代码有几个问题:

  • 您可以使用索引器从列表中访问元素,而不是使用更为口头的ElementAt()。它对我来说看起来更干净
  • Equals()仅比较列表的引用,而不是内容。所以[&#34; 1&#34;,&#34; 2&#34;,&#34; 3&#34;]和[&#34; 1&#34;,&#34; 3&#34;,& #34; 2&#34;]会给出错误的
  • 另一件事是你比较list1中的元素和其他答案提及

这是我尝试使用LINQ:

    var list2 = list1.GroupBy(e => 
                    e.requestorList.OrderBy(r => r)       //Order list ascending
                                   .Aggregate((i, j) => i + j))    //Append elements in the list together to create "signature" of the list
                    .Where(g => g.Count() > 1)          //Select grouping that has at least 2 elements
                    .SelectMany(g => g);         //Flatten all the lists into single list

我使用OrderBy()和Aggregate()来创建&#34;签名&#34;对于你的requestorList,所以[&#34; 1&#34;,&#34; 3&#34;,&#34; 2&#34;]和[&#34; 1&#34;,&#34; 2& #34;,&#34; 3&#34;]具有相同的签名&#34; 123&#34;,然后按该签名对元素进行分组

不确定你在list2中的期望,所以我只是把所有重复的requestorList压缩成单个列表