这里我根据另一个列表将列表合并到另一个列表的末尾。如果发现processdetails列表中没有的任何项目,它应该根据路由计划列表中的顺序对processdetails列表进行排序。订单并将其添加到processdetails列表。简单地说它只是根据另一个列表合并两个列表。下面的代码工作正常,我想知道是否有更简洁的方法来执行此操作。如果可能在linq。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SortByList
{
public class OnGoingProcess
{
public long Id { get; set; }
public string Name { get; set; }
public string Code { get; set; }
}
class Program
{
static void Main(string[] args)
{
var processDetails = new List<OnGoingProcess>();
processDetails.Add(new OnGoingProcess() { Id = 120, Name = "Process 29", Code = "T20" });
processDetails.Add(new OnGoingProcess() { Id = 100, Name = "Process 2", Code = "A20" });
processDetails.Add(new OnGoingProcess() { Id = 99, Name = "Process 3", Code = "S20" });
processDetails.Add(new OnGoingProcess() { Id = 85, Name = "Process 229", Code = "B20" });
processDetails.Add(new OnGoingProcess() { Id = 220, Name = "Process 39", Code = "C20" });
processDetails.Add(new OnGoingProcess() { Id = 15, Name = "Process 20", Code = "D20" });
processDetails.Add(new OnGoingProcess() { Id = 101, Name = "Process 129", Code = "G20" });
var routePlans = new List<OnGoingProcess>();
routePlans.Add(new OnGoingProcess() { Id = 100, Name = "Process 2" });
routePlans.Add(new OnGoingProcess() { Id = 120, Name = "Process 29" });
routePlans.Add(new OnGoingProcess() { Id = 222, Name = "Process new" });
routePlans.Add(new OnGoingProcess() { Id = 85, Name = "Process 229" });
routePlans.Add(new OnGoingProcess() { Id = 101, Name = "Process 129" });
var sortedPlans = new List<OnGoingProcess>();
foreach (var plan in routePlans)
{
var selectedDetails = processDetails.Where(x => x.Id == plan.Id).ToList();
if (selectedDetails.Any())
{
sortedPlans.AddRange(selectedDetails);
processDetails.RemoveAll(x => x.Id == plan.Id);
}
else
{
sortedPlans.Add(plan);
}
}
processDetails.AddRange(sortedPlans);
foreach (var sorted in processDetails)
{
Console.WriteLine("Id : " + sorted.Id + " Name : " + sorted.Name + " Code : " + sorted.Code );
}
Console.ReadKey();
//Id : 99 Name : Process 3 Code : S20
//Id : 220 Name : Process 39 Code : C20
//Id : 15 Name : Process 20 Code : D20
//Id : 100 Name : Process 2 Code : A20
//Id : 120 Name : Process 29 Code : T20
//Id : 222 Name : Process new Code :
//Id : 85 Name : Process 229 Code : B20
//Id : 101 Name : Process 129 Code : G20
}
}
}
答案 0 :(得分:3)
你在做什么本质上是一个full outer join,它可以通过right antijoin结合left outer join高效实现LINQ:
var result =
(from pd in processDetails
join rp in routePlans on pd.Id equals rp.Id into match
where !match.Any()
select pd)
.Concat
(from rp in routePlans
join pd in processDetails on rp.Id equals pd.Id into match
from pd in match.DefaultIfEmpty()
select pd ?? rp)
.ToList();
答案 1 :(得分:1)
我已经设法使用LINQ,使用此查询:
不在routePlans
:
var orderedFirst = processDetails.Where(x=>!routePlans.Any(r=>r.Id==x.Id));
然后构建要订购的项目列表,它包含尚未排序的processdetails和不在processdetails
中的路线计划:
var toOrder = processDetails.Except(orderedFirst).ToList();
toOrder.AddRange(routePlans.Where(r=>!toOrder.Any(o=>o.Id==r.Id)));
而不是在routeplans
中订购此列表:
var orderedSecond = toOrder
.OrderBy(x => routePlans.Select((t,i) => new {i, t.Id} )
.First(t=>t.Id==x.Id)
.i);
而不是合并两个列表:
var result = orderedFirst.ToList();
result.AddRange(orderedSecond);
result.Dump();
结果与您的相同:
但是linq查询不是很漂亮和可读。