2014-09-25 31 views
0

我有一个值列表,用于对另一列值进行排序,但我一直遇到的问题是如果我删除了要排序的值中的两个值,那么需要排序的值列表中的两个值就会丢失这两个值,因为它在有序值列表中找不到。C#按另一个列表排序并将未找到的列表添加到列表末尾

这是我尝试

尝试的例子1

universites = universites.OrderBy(d => listOrderedUniversites.IndexOf(d)).ToList(); 

的社区学院是一个列表,该orderedUniversity是模型的列表中,listOrderedUniversites是一个列表。

然而,这确实拉出了所有的值,但它并没有命令它们。

---更新---

这是我

universites = new List<SelectListItem>(); 
universites.Add(new SelectListItem() 
{ 
    Value = 1, 
    Test = "University 1" 
}); 
universites.Add(new SelectListItem() 
{ 
    Value = 2, 
    Test = "University 2" 
}); 
universites.Add(new SelectListItem() 
{ 
    Value = 3, 
    Test = "University 3" 
}); 

ordering = new int[] {3, 1, 2}; 

所以我需要通过int数组为了我的清单;

+2

您能提供样品清单和预期结果吗?你的问题目前有点不清楚,因为我看不出如何通过另一个列表排列一个列表,如果它们长度不一样,以及为什么一个列表中的项目也应该在另一个列表中。 – 2014-09-25 08:26:34

+1

'd'是什么?它是一些“大学”类吗?如果是,你是否覆盖了这个类的'Equals'和'GetHashCode'? – 2014-09-25 08:27:47

+0

@Matthew好吧,让我们说有序大学是{1,5,4,2,3},大学是{1,2,3,4,5,6,7}我想命令大学看起来像{1, 5,4,2,3,6,7},列表的长度可能不同的原因是我将它们从数据库中提取出来,并且只要添加了值,该表就可以增加,因此需要将新值添加到列表和有序列表中,否则它将永远不会显示 – Canvas 2014-09-25 08:31:40

回答

0

[编辑]这个问题很不清楚,我不知道这是否是正确的答案。我不应该试图回答这个问题,但我会在这里等待OP的澄清。

您可以使用Enumerable.Intersect()Enumerable.Except()来做到这一点。

下面是使用它的整数(为简单起见)演示了一个编译的例子:

using System; 
using System.Collections.Generic; 
using System.Linq; 

namespace Demo 
{ 
    internal class Program 
    { 
     private static void Main() 
     { 
      IEnumerable<int> ordered = new [] {1, 5, 4, -1, 2, 3}; 
      IEnumerable<int> unordered = Enumerable.Range(1, 7); 

      // This prints 1, 5, 4, 2, 3, 6, 7: 

      Console.WriteLine(string.Join(", ", MyOrderBy(unordered, ordered))); 
     } 

     public static IEnumerable<T> MyOrderBy<T>(IEnumerable<T> unordered, IEnumerable<T> ordered) 
     { 
      return ordered.Intersect(unordered).Concat(unordered.Except(ordered)); 
     } 
    } 
} 

注意,这个假设有任一列表中没有重复。

另请注意,Intersect()Except()正常工作,元素的类型必须有一个GetHashCode()Equals()实施适用于该类型。

这将意味着你的University类型正确覆盖它们。

+0

永远不会是重复的,但是你可以做一个List 和一个int数组吗? – Canvas 2014-09-25 08:54:34

+0

@Canvas因为我使用IEnumerable ',它可以处理任何实现了'IEnumerable '的东西,这几乎每一个集合类型,包括整数和'List '的数组。您可以将列表和数组传递给上面显示的'OrderBy()'方法。如果你希望返回类型是一个列表,只需在返回的值上调用'ToList()'。同样,如果你想要一个数组,可以调用'ToArray()'。 – 2014-09-25 08:55:46

+0

请注意德米特里的评论如下:为了能够使用'Intersect()'和'Except()',你必须能够正确地比较项目,所以对于一个自定义类型,你需要重写'GetHashCode()'和'Equals ()'的类型。 – 2014-09-25 09:01:46

0

我建模正确和错误行为:

List<String> universites = new List<String>() { 
    "E", "A", "D", "C", "B" 
    }; 

    // Desired order: A, C, D; X, Z will be ignored 
    List<String> listOrderedUniversites = new List<String>() { 
    "A", "C", "D", "X", "Z" 
    }; 

    // result is "E, B, A, C, D": 
    // "E" and "B" are not in listOrderedUniversites 
    // and so IndexOf() returns -1 for such values 
    // that's why "E", "B" appears in the begining of the list 
    // all the other items ("A", "C", "D") are sorted as expected 
    String result = String.Join(", ", 
    universites.OrderBy(item => listOrderedUniversites.IndexOf(item))); 

但是,如果你把说的,而是StringBuilder一切String顺心

List<StringBuilder> universites = new List<StringBuilder>() { 
    new StringBuilder("E"), 
    new StringBuilder("A"), 
    new StringBuilder("D"), 
    new StringBuilder("C"), 
    new StringBuilder("B") 
    }; 

    List<StringBuilder> listOrderedUniversites = new List<StringBuilder>() { 
    new StringBuilder("A"), 
    new StringBuilder("C"), 
    new StringBuilder("D"), 
    new StringBuilder("X"), 
    new StringBuilder("Z") 
    }; 

    // Wrong order: "E, A, D, C, B" (note "A, D, C") 
    String result = String.Join(", ", universites 
    .OrderBy(item => listOrderedUniversites.IndexOf(item)) 
    .Select(item => item.ToString())); 

的原因是,你必须覆盖Equals()GetHashCode()方法 让List.IndexOf()正常工作。默认Equals()GetHashCode()实现考虑实例地址(两个对象相同,当且仅当它们实际上是对同一实例的一个引用),而不是它们的

相关问题