我有IEnumerable<Process>
。
public class Process
{
public string Id { get; set; }
public string Name { get; set; }
public int Type { get; set; }
}
我想根据IEnumerable<Process>
订购此Type
。排序应基于预定义的顺序。
序列是:7,3,4,1。因此,如果集合具有这些值中的任何一个,它们应该首先出现在顺序7,然后是3等等。
然后任何其他Type
应该按升序排列。
根据预定义的顺序订购此产品的正确方法是什么?我应该将序列本身定义为enum
?
答案 0 :(得分:4)
如果数字序列是List<int>
,您可以按索引排序:
var ordered = processes
.OrderByDescending(p => numbers.Contains(p.Type))
.ThenBy(p => numbers.IndexOf(p.Type));
或者,使用LINQ的查询语法更有效和可读:
var ordered = from proc in processes
let index = numbers.IndexOf(proc.Type)
orderby index == -1, index
select proc;
index == -1
返回bool
,其中true
高于false
。这就是整个伎俩。
顺便说一下,Array
还有IndexOf
方法:
let index = Array.IndexOf(numArray, proc.Type)
答案 1 :(得分:1)
从这些项创建一个查找值以进行排序(在本例中为该列表中的索引),然后您可以轻松地将每个值投影到要排序的值:
var typeOrders = new int[]{7,3,4,1};
var typeOrderLookup = typeOrders.Select((type,i)=>new{type,i})
.ToDictionary(pair => pair.type, pair => pair.i);
var query = someData.OrderBy(process => typeOrderLookup[process.Type]);
答案 2 :(得分:0)
我从您那里得到的问题是,如果您的流程列表包含Process
中Type
sequence = (7, 3, 4, 1)
的任何sequence
,那么这些流程应首先显示基于该Type
的排序{ {1}},然后应根据Type
按升序对进程列表的其余部分进行排序。
我所做的基本上是创建两个列表,最后将它们联合起来。第一个列表仅包含sequence
中Type
的进程,该进程根据序列排序,第二个列表包含原始列表的其余部分,只按List<Process> processList = new List<Process>()
{
new Process() { Id = "1", name = "1", Type = 7},
new Process() { Id = "2", name = "2", Type = 1},
new Process() { Id = "3", name = "3", Type = 4},
new Process() { Id = "4", name = "4", Type = 3},
new Process() { Id = "5", name = "5", Type = 9},
new Process() { Id = "6", name = "6", Type = 8},
};
List<int> sequence = new List<int>() { 7, 3, 4, 1 };
var pl = processList.Where(p => sequence.Contains(p.Type))
.OrderBy(p => sequence.IndexOf(p.Type))
.Union(processList.Where(p => !sequence.Contains(p.Type))
.OrderBy(p => p.Type));
排序。
以下是您使用示例数据的答案:
{{1}}
答案 3 :(得分:0)
我们可以通过一个表达式来实现:
var order = new int[] { 7, 3, 4, 1 };
var orderedProccesses = order.Select(i => processes.FirstOrDefault(p => p.Type == i))
.Where(p => p != null)
.Concat(processes.Where(p => !order.Contains(p.Type)).OrderBy(p => p.Type))
.ToArray();
首先将定义的订单列表映射到相应的流程:
order.Select((i) => processes.FirstOrDefault(p => p.Type == i))
然后,进行健全性检查,因为不能保证订单中的每个项目都有相应的流程:
.Where((p) => p != null)
然后添加其余的进程并按类型
对它们进行排序 .Concat(processes.Where((p) => !order.Contains(p.Type)).OrderBy((p) => p.Type))