Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 以一种奇怪的方式将两个列表连接在一起_C#_Linq - Fatal编程技术网

C# 以一种奇怪的方式将两个列表连接在一起

C# 以一种奇怪的方式将两个列表连接在一起,c#,linq,C#,Linq,我有一个问题,我想我可以用LINQ解决,但我不确定如何解决 我有两个列表,前一个和当前。Previous是我在调用Process.GetProcesses()后创建的自定义对象列表。Current是当时从Process.GetProcesses()返回的内容 我要做的是,对于当前列表中与上一个列表具有相同ID的任何对象,将其放入列表C。如果上一个列表中有一个项目不在当前列表中,请不要将其放入C。如果当前列表中有一个项目不在上一个列表中,但该对象在该列表中(与上一个列表中创建的对象不同) 我之所以

我有一个问题,我想我可以用LINQ解决,但我不确定如何解决

我有两个列表,前一个和当前。Previous是我在调用Process.GetProcesses()后创建的自定义对象列表。Current是当时从Process.GetProcesses()返回的内容

我要做的是,对于当前列表中与上一个列表具有相同ID的任何对象,将其放入列表C。如果上一个列表中有一个项目不在当前列表中,请不要将其放入C。如果当前列表中有一个项目不在上一个列表中,但该对象在该列表中(与上一个列表中创建的对象不同)

我之所以要这样做,是因为从当前创建这些对象需要很长时间,如果已经创建了,我只想保存它们,但我仍然需要一个更新的列表

范例

列表A:{{ID:1,Data1:a1,Data2:a1},{ID:2,Data1:a2,Data2:a2},{ID:3,Data1:a3,Data2:a3}

List B: { {ID: 1, Stuff: s1}, {ID: 2, Stuff: s2}, {ID: 4, Stuff: s4}}
做一些魔术

List C: { {ID: 1, Data1: a1, Data2: a1}, {ID: 2, Data1: a2, Data2: a2}, {ID: 4, Stuff: s4}

我的想法是在这两个对象上使用某种正确的联接,但我不确定。如果在联接过程中,我可以当场为ID:4创建新对象,而不是为这些类型的对象迭代新列表以更新到我的自定义对象,那么我就可以获得额外的好处。

1根据ID为列表a构建哈希表。(HashA) 2检查列表B中的元素。如果HashA包含元素ID,则使用列表A中的对象(此处:从hashtable检索),否则,使用当前元素)

试验 输出

[
 {"ID": 1, "Data1": "a1", "Data2": "a1", "Stuff": null},
 {"ID": 2, "Data1": "a2", "Data2": "a2", "Stuff": null },
 {"ID": 4, "Data1": null, "Data2": null, "Stuff": "s4" }
]

创建一个新列表,其中两个列表中的ID都匹配

然后将新列表与前一列表中不存在当前ID的当前列表合并:

var previous = new[]
{
    new Data{ID = 1, Data1 = "a1", Data2 = "a1" },
    new Data{ID = 2, Data1 = "a2", Data2 = "a2" },
    new Data{ID = 3, Data1 = "a3" },
};

var current = new[]
{
    new Data{ID = 1, Stuff = "s1" },
    new Data{ID = 2, Stuff = "s2" },
    new Data{ID = 4, Stuff = "s4" },
};

var newList = previous.Join(current, p => p.ID, c => c.ID, (p, c) => p);

newList = newList.Concat(current.Where(c => !previous.Any(p => p.ID == c.ID)));

您可以使用
Linq
previous
中选择所有在
current
中有匹配项的项目,然后选择那些在
current
中有所有在
previous
中没有匹配项的项目:

var listC = previous
    .Where(p => current.Any(c => c.ID == p.ID))
    .Concat(current.Where(c => previous.All(p => p.ID != c.ID)));

Asuming A是previous,B是current,C是C:内部连接列表A和B,以获取需要添加到C中的内容。然后将B合并到A中,以获取A应包含的新值。最后,LINQ将对内存中的任意两个集合执行类似于DB查询语言的操作。因此,您可以将它们视为3个数据库表/结果集。
var previous = new[]
{
    new Data{ID = 1, Data1 = "a1", Data2 = "a1" },
    new Data{ID = 2, Data1 = "a2", Data2 = "a2" },
    new Data{ID = 3, Data1 = "a3" },
};

var current = new[]
{
    new Data{ID = 1, Stuff = "s1" },
    new Data{ID = 2, Stuff = "s2" },
    new Data{ID = 4, Stuff = "s4" },
};

var newList = previous.Join(current, p => p.ID, c => c.ID, (p, c) => p);

newList = newList.Concat(current.Where(c => !previous.Any(p => p.ID == c.ID)));
var listC = previous
    .Where(p => current.Any(c => c.ID == p.ID))
    .Concat(current.Where(c => previous.All(p => p.ID != c.ID)));