【问题标题】:Why a .Union() changes the order of the items? [duplicate]为什么 .Union() 会更改项目的顺序? [复制]
【发布时间】:2012-09-21 10:25:57
【问题描述】:

可能重复:
.Union() changes the order of the items?

根据this 问题(没有场景/示例;你应该删除它,我不能)这是我的问题:

我注意到,如果我在集合Attachment[] 之间执行Union,而不是Intersect,则项目的顺序“可以”改变。

这是我的代码:

    GalleryDataClassesDataContext db = new GalleryDataClassesDataContext();
    List<Attachment> Allegati = db.ExecuteQuery<Attachment>("EXEC SelectAttachmentsByKey @Key={0}, @IDCliente={1}", new object[] { "", "47" }).ToList();
    List<Attachment> AllegatiPerCategorie = new List<Attachment>();

    AllegatiPerCategorie = AllegatiPerCategorie.Union(db.AttachmentAttachmentCategories.Where(aac => aac.IDAttachmentCategory == 72).OrderBy(p => p.Ordine == null ? 1 : 0).ThenBy(p => p.Ordine).Select(aac => aac.Attachment)).ToList();
    Allegati = Allegati.Intersect(AllegatiPerCategorie).ToList();

    count = 0;
    foreach (Attachment a in AllegatiPerCategorie)
    {
        Response.Write(count.ToString() + " - " + a.IDAttachment + "<br />");
        count++;
    }

    Response.Write("<br />### FILTERED ###<br /><br />");

    count = 0;
    foreach (Attachment a in Allegati)
    {
        Response.Write(count.ToString() + " - " + a.IDAttachment + "<br />");
        count++;
    }

输出是:

0 - 6769
1 - 6792
2 - 6771
3 - 6699
4 - 6632
5 - 6774
6 - 6595
7 - 6602
8 - 6641
9 - 6643
10 - 6764
11 - 6634
12 - 6642
13 - 6660
14 - 6640
15 - 6665
16 - 6673
17 - 6767
18 - 6772
19 - 6766
20 - 6763
21 - 6768
22 - 6644
23 - 6635
24 - 6633
25 - 6793
26 - 6677
27 - 6608
28 - 6610
29 - 6558
30 - 6563
31 - 6631
32 - 6604
33 - 6606
34 - 6607
35 - 6596
36 - 6597
37 - 6598
38 - 6599
39 - 6600
40 - 6471
41 - 6470
42 - 6469
43 - 6601
44 - 6603
45 - 6663
46 - 6664
47 - 6645
48 - 6637
49 - 6638
50 - 6609
51 - 6611
52 - 6612
53 - 6613
54 - 6614
55 - 6615
56 - 6616
57 - 6617
58 - 6618
59 - 6619
60 - 6620
61 - 6622
62 - 6567
63 - 6568
64 - 6569
65 - 6570
66 - 6571
67 - 6572
68 - 6573
69 - 6575
70 - 6576
71 - 6577
72 - 6579
73 - 6580
74 - 6581
75 - 6582
76 - 6583
77 - 6584
78 - 6585
79 - 6586
80 - 6587
81 - 6588
82 - 6589
83 - 6590
84 - 6591
85 - 6592
86 - 6593
87 - 6594
88 - 6765

### FILTERED ###

0 - 6769
1 - 6792
2 - 6771
3 - 6699
4 - 6774
5 - 6595
6 - 6602
7 - 6634
8 - 6642
9 - 6640
10 - 6660
11 - 6665
12 - 6673
13 - 6772
14 - 6766
15 - 6768
16 - 6644
17 - 6635
18 - 6633
19 - 6793
20 - 6677

好吧,请注意 AllegatiPerCategorie 列表中值 66606640 的顺序:66606640(在位置 1314)。

现在,在Allegati 上以相同的值顺序观看:66406660 之前(在位置 910 )。

为什么会有这种行为?我该如何解决?谢谢

【问题讨论】:

  • 不,不要关闭这个!关闭另一个!请给我举个例子!!!
  • @markzzz - 你有例子吗?太好了,然后转到您的其他问题,并使用edit 链接...
  • 请把AllegatiPerCategorie(联合前)的内容,Union()-argument和结果贴出来。
  • 该死的你是对的!如果我先浏览 Allegati,6640 在 6660 之前...怎么可能?在存储过程上 6660 在 6640 之前...

标签: c# .net linq list


【解决方案1】:

MSDN 状态:

当枚举该方法返回的对象时,Union 依次枚举第一个和第二个,并产生每个尚未产生的元素。

这是一个演示该行为的简短示例:

new int[] {1}.Union(new int[] {1, 2, 3}) // returns: 1,2,3
new int[] {2}.Union(new int[] {1, 2, 3}) // returns: 2,1,3
new int[] {3}.Union(new int[] {1, 2, 3}) // returns: 3,1,2

new int[] {1,3,5}.Union(new int[] {2, 4}) // returns: 1,3,5,2,4

【讨论】:

  • +1 易于理解,很好的示例。
【解决方案2】:

Union:

使用默认相等比较器生成两个序列的 set 并集。

根据定义,集合不包含重复项,也没有固有排序。

还有:

此方法从返回集中排除重复项。这与 Concat&lt;TSource&gt; 方法的行为不同,后者返回输入序列中的所有元素,包括重复项。

还有:

当枚举该方法返回的对象时,Union 依次枚举第一个和第二个,并产生每个尚未产生的元素。

【讨论】:

  • 是的,但实际上并没有!根据规范,它应该“保持”第一个列表的顺序,而不是第二个......
  • @markzzz - 规范说列表将一个接一个地枚举(第一个,然后是第二个)。它并不是说每个列表都会在内部以任何特定的顺序进行枚举。
  • 不,好的,但是如果在第一个列表中 6660 在 6640 之前,则之后的顺序必须相同:O
  • @markzzz - 不,你误读了。如果6660 在第一个列表中,6640 在第二个列表中,那么顺序将如您所愿(第一个列表中的值将显示在第二个列表中的值之前)。不能保证第一个(或第二个)列表中的迭代顺序会是原来的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多