2011-03-01 102 views
3
var listOne = new string[] { "dog", "cat", "car", "apple"}; 
var listTwo = new string[] { "car", "apple"}; 

我需要的是按listTwo中的项目顺序排列listOne(如果存在)。所以新的列表将按照这个顺序; “汽车”,“苹果”,“狗”,“猫”从另一个数组顺序排序一个数组?

我想在LINQ中做到这一点,

var newList = from l1 in listOne 
       join l2 in listTwo on l1 equals l2 in temp 
       from nl temp.DefaultIfEmpty() 
       select nl; 

但是它返回null显然我的Linq-Fu很弱。任何意见表示赞赏。

+1

“listOne”中是否存在重复?如果是这样,他们应该保存吗? – 2011-03-01 18:35:03

回答

4

您需要列表1中的所有项目,然后是listOne中的其余项目?

var results = listTwo.Intersect(listOne).Union(listOne); 
foreach (string r in results) 
{ 
    Console.WriteLine(r); 
} 
+1

为什么你需要第二个Except?这是一个联盟;他们不会出现两次。 – 2011-03-01 18:33:16

+0

你从哪里得知它是一个工会? – 2011-03-01 18:36:31

+0

我已经改变了Concat一分钟,但你是对的。没有这个例外的联盟可能更优雅。 listTwo.Intersect(那么listOne).Union(那么listOne); – 2011-03-01 18:38:41

3

嗯,让我重组你的排序要求:

  1. 首先,所有的从第一个列表中的项目,这也是目前在第二个列表,并返回它们的顺序它们出现在该名单,:第二个列表中的所有元素(如果它们出现在第一个列表中)
  2. 然后,第一个列表中不在第二个列表中的所有项目,然后按它们出现的顺序返回那第一个名单

该代码会做的伎俩:

void Main() 
{ 
    var listOne = new string[] { "dog", "cat", "car", "apple"}; 
    var listTwo = new string[] { "car", "apple"}; 

    var elements1 = 
     from element in listTwo 
     where listOne.Contains(element) 
     select element; 
    var elements2 = 
     from element in listOne 
     where !listTwo.Contains(element) 
     select element; 

    elements1.Concat(elements2).Dump(); 
} 

你也可以把它改写没有LINQ语法使它有点短:

void Main() 
{ 
    var listOne = new string[] { "dog", "cat", "car", "apple"}; 
    var listTwo = new string[] { "car", "apple"}; 

    var elements = listTwo.Where(e => listOne.Contains(e)) 
     .Concat(listOne.Where(e => !listTwo.Contains(e))); 

    elements.Dump(); 
} 

输出(通过LINQPad):

car 
apple 
dog 
cat 
+0

好的解决方案,具有listOne {“A”,“A”,“B”,“C”}和listTwo {“A”,“C”} IMO的BTW应该产生“{”A“,”A “,”C“,”B“}'不是'{”A“,”C“,”B“},就像你的代码一样......不知道OP是否需要这样做) – digEmAll 2011-03-01 18:39:38

+0

顺便说一句'Intersect'和'Except'比'Where''Contains'更有效率 – 2011-03-01 18:42:06

相关问题