C# 新任务{Id=10,Action=“Save”,Source=25,Target=27}, 新任务{Id=16,Action=“Save”,Source=29,Target=31}, 新任务{Id=0,Action=“Edit”,Source=31,Target=37}, }; var collectTasks=(来自任务中的t) 其中!tasks.Any(t1=>(t1.Target==t.Source)&&&(t1.Action==t.Action)&&(t1.Id!=t.Id)) 选择t.ToList(); foreach(collectTasks中的var ct) { 做{ var t1=任务中的t,其中((ct.Target==t.Source)&&&(ct.Action==t.Action)&&(ct.Id!=t.Id))选择t; 如果(t1.Count()==0){break;} ct.Target=t1.First().Target; }虽然(正确); } foreach(collectTasks中的var t) { WriteLine(“Action={0},Source={1},Target={2}”,t.Action,t.Source,t.Target); } }
此过程将在一次过程中完成所需操作,保留无法合并的项目的“Id”值 你会看到它在一个有序的列表上工作,所以严格地说,这里有一些LINQ隐藏的活动;但一般来说,您会发现LINQ查询会产生开销,这使得then总是比数组上的循环慢C# 新任务{Id=10,Action=“Save”,Source=25,Target=27}, 新任务{Id=16,Action=“Save”,Source=29,Target=31}, 新任务{Id=0,Action=“Edit”,Source=31,Target=37}, }; var collectTasks=(来自任务中的t) 其中!tasks.Any(t1=>(t1.Target==t.Source)&&&(t1.Action==t.Action)&&(t1.Id!=t.Id)) 选择t.ToList(); foreach(collectTasks中的var ct) { 做{ var t1=任务中的t,其中((ct.Target==t.Source)&&&(ct.Action==t.Action)&&(ct.Id!=t.Id))选择t; 如果(t1.Count()==0){break;} ct.Target=t1.First().Target; }虽然(正确); } foreach(collectTasks中的var t) { WriteLine(“Action={0},Source={1},Target={2}”,t.Action,t.Source,t.Target); } },c#,list,linq,merge,C#,List,Linq,Merge,此过程将在一次过程中完成所需操作,保留无法合并的项目的“Id”值 你会看到它在一个有序的列表上工作,所以严格地说,这里有一些LINQ隐藏的活动;但一般来说,您会发现LINQ查询会产生开销,这使得then总是比数组上的循环慢 private List<Task> Merge(List<Task> list) { var result = new List<Task>(); var maxId = list.Max(
private List<Task> Merge(List<Task> list)
{
var result = new List<Task>();
var maxId = list.Max(x => x.Id) + 1;
// order list for this algo to work
var listO = list.OrderByDescending(x => x.Action).ThenBy(x => x.Source).ToArray();
// create seed and counter
Task seed = listO[0];
var ctr = 0;
for (var i = 0; i < listO.Length - 1; i++)
{
if (listO[i + 1].Source == listO[i].Target && listO[i + 1].Action == listO[i].Action && listO[i + 1].Action == seed.Action)
{
// if the next is the last, merge it now
if (i + 1 == listO.Length - 1)
result.Add(new Task() { Id = maxId++, Action = seed.Action, Source = seed.Source, Target = listO[i].Target });
// the next item qualifies for merge, move to next
ctr++;
continue;
}
// next item does not qualify for merge, merge what we have or just add the item if ctr == 0
result.Add(ctr == 0 ? seed : new Task() { Id = maxId++, Action = seed.Action, Source = seed.Source, Target = listO[i].Target });
// reset seed record + counter
seed = listO[i+1];
ctr = 0;
// if the next item is the last, it belongs in the list as is
if (i + 1 == listO.Length - 1) result.Add(seed);
}
return result;
}
私有列表合并(列表)
{
var result=新列表();
var maxId=list.Max(x=>x.Id)+1;
//此算法工作的订单列表
var listO=list.OrderByDescending(x=>x.Action).ThenBy(x=>x.Source.ToArray();
//创建种子和计数器
任务种子=listO[0];
var-ctr=0;
对于(变量i=0;i
由于它是一个列表,您可以使用索引和单程进行
循环,将当前项目与上一个/下一个项目组合在一起。你在谈论的foreach循环有哪些?但不确定如何获得Id=22
。请查看GroupBy()。@Sinatr Id=22是对象的内部Id属性,而不是列表中的索引。您能否假设只有下一个任务是合并的候选任务?我认为GroupBy
没有帮助的是:“但只有在上面项的目标值等于跟随者项的源值的情况下”什么是跟随者?您的解决方案假设任务已经像这样排序tasks.OrderBy(x=>x.Action)。然后by(x=>x.source)
Yes,但正如我所理解的,OP有预定义的顺序(按id?),所以我不确定是否应该通过操作
或源代码
来实现。仍然有效的评论-如果我错了,OP总是可以添加所需的OrderBy
。谢谢。是的,它已经订购了!!我正在测试这是否是我正在寻找的解决方案。我不知道更多信息。我正在构思一个新项目来尝试一下。Upvote从我这里。
var result = tasks.Aggregate(new List<Item>(), (acc, current) =>
{
if (acc.Count > 0)
{
var prev = acc[acc.Count - 1];
if (prev.Action == current.Action && prev.Target == current.Source)
{
// update previous target
prev.Target = current.Target;
}
// otherwise just add
else acc.Add(current);
}
else acc.Add(current);
return acc;
});
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication33
{
class Program
{
static void Main(string[] args)
{
List<Task> tasks = new List<Task>() {
new Task() { Id = 1, Action = "Save", Source = 12, Target = 18},
new Task() { Id = 4, Action = "Save", Source = 18, Target = 21},
new Task() { Id = 7, Action = "Save", Source = 21, Target = 23},
new Task() { Id = 6, Action = "Save", Source = 23, Target = 25},
new Task() { Id = 10, Action = "Save", Source = 25, Target = 27},
new Task() { Id = 16, Action = "Save", Source = 29, Target = 31},
new Task() { Id = 0, Action = "Edit", Source = 31, Target = 37}
};
for(int i = tasks.Count - 1; i >= 0; i--)
{
int source = tasks[i].Source;
List<int> match = tasks.Select((x, index) => new { x = x, i = index }).Where(x => (x.x.Target == source) && (tasks[i].Action == tasks[x.i].Action)).Select(x => x.i).ToList();
if (match.Count > 0)
{
tasks[match[0]].Target = tasks[i].Target;
tasks.RemoveAt(i);
}
}
}
}
public class Task
{
public int Id { get; set; }
public string Action { get; set; }
public int Source { get; set; }
public int Target { get; set; }
}
}
var grouped = tasks
.GroupBy(t => t.Action, (k, g) => g
.Segment((s, f, a) => s.Source != f.Target)
.Select(c => new
{
c.First().Source,
c.Last().Target,
Action = k
})));
public class Tasks
{
public int Id;
public string Action;
public int Source;
public int Target;
}
static void Main(string[] args)
{
List<Tasks> tasks = new List<Tasks>{
new Tasks{Id=1,Action="Save",Source= 12,Target=18},
new Tasks{Id=4,Action="Save",Source= 18,Target=21},
new Tasks{Id=7,Action="Save",Source= 21,Target=23},
new Tasks{Id=6,Action="Save",Source= 23,Target=25},
new Tasks{Id=10,Action="Save",Source= 25,Target=27},
new Tasks{Id=16,Action="Save",Source= 29,Target=31},
new Tasks{Id=0,Action="Edit",Source= 31,Target=37},
};
var collectTasks = (from t in tasks
where !tasks.Any(t1 => (t1.Target == t.Source)&&(t1.Action == t.Action)&&(t1.Id!=t.Id))
select t).ToList();
foreach (var ct in collectTasks)
{
do{
var t1 = from t in tasks where ((ct.Target == t.Source)&&(ct.Action == t.Action)&&(ct.Id!=t.Id)) select t;
if (t1.Count() == 0) { break; }
ct.Target = t1.First().Target;
} while (true);
}
foreach (var t in collectTasks)
{
Console.WriteLine("Action = {0}, Source = {1}, Target = {2}", t.Action, t.Source, t.Target);
}
}
private List<Task> Merge(List<Task> list)
{
var result = new List<Task>();
var maxId = list.Max(x => x.Id) + 1;
// order list for this algo to work
var listO = list.OrderByDescending(x => x.Action).ThenBy(x => x.Source).ToArray();
// create seed and counter
Task seed = listO[0];
var ctr = 0;
for (var i = 0; i < listO.Length - 1; i++)
{
if (listO[i + 1].Source == listO[i].Target && listO[i + 1].Action == listO[i].Action && listO[i + 1].Action == seed.Action)
{
// if the next is the last, merge it now
if (i + 1 == listO.Length - 1)
result.Add(new Task() { Id = maxId++, Action = seed.Action, Source = seed.Source, Target = listO[i].Target });
// the next item qualifies for merge, move to next
ctr++;
continue;
}
// next item does not qualify for merge, merge what we have or just add the item if ctr == 0
result.Add(ctr == 0 ? seed : new Task() { Id = maxId++, Action = seed.Action, Source = seed.Source, Target = listO[i].Target });
// reset seed record + counter
seed = listO[i+1];
ctr = 0;
// if the next item is the last, it belongs in the list as is
if (i + 1 == listO.Length - 1) result.Add(seed);
}
return result;
}