从一个列表中删除元素如果不包含在另一个列表中。 C# [重复]
Posted
技术标签:
【中文标题】从一个列表中删除元素如果不包含在另一个列表中。 C# [重复]【英文标题】:Removing Elements From One List If not contained in another List. C# [duplicate] 【发布时间】:2019-10-11 01:13:39 【问题描述】:我从List<> A
中删除不在List<> B
中的元素的最佳方法是什么。最重要的是,在我删除 Element
之前,我需要在 Element
上运行一个函数(当值更改时运行回调)。
举例
List<Chunk> ActiveChunks = //List Of Active Chunks.
void UpdateChunks()
List<Chunk> chunks = //Chunks To Activate
if (ActiveChunks[Element] is not Contained In chunks)
A.Active = False
A.Remove[Element]
//After Removing Chunks That do not exist in "chunks" add from chunks to ActiveChunks What is not In already in Chunks
我的代码是什么样子的
private List<Chunk> ActiveChunks = new List<Chunk>();
private void OnPlayerMoved(Character c)
//Current chunk That Player is in
List<Chunk> chunks = new List<Chunk>();
for (int i = -(GameManager.ViewRange - 1); i < GameManager.ViewRange - 1; i++)
Chunk chunk = world.ChunkAtWorldPos(c.PosX + i, c.PosY + i);
if (chunk != null)
chunks.Add(chunk);
if (ActiveChunks.Count > 0)
foreach (Chunk chunk in ActiveChunks)
if (chunks.Contains(chunk) == false)
chunk.Active = false;
//This Line From Answer down Below
ActiveChunks.RemoveAll(x => x.Active == false);
foreach (Chunk chunk in chunks)
if (ActiveChunks.Contains(chunk) == false)
chunk.Active = true;
ActiveChunks.Add(chunk);
else
ActiveChunks.AddRange(chunks);
public class Chunk
//Position
public readonly int X;
public readonly int Y;
public Tile[,] Tiles;
private bool active = false;
public bool Active
getreturn active;
set
if (value == true && value != active)
cbOnActivate?.Invoke(this);
else if (value != active)
cbOnDeactivate?.Invoke(this);
active = value;
Action<Chunk> cbOnActivate;
Action<Chunk> cbOnDeactivate;
//Constructor
public Chunk(int X, int Y)
this.X = X;
this.Y = Y;
void RegisterOnActivateCallback(Action<Chunk> callback)
cbOnActivate += callback;
void RegisterOnDeactivateCallback(Action<Chunk> callback)
cbOnActivate += callback;
【问题讨论】:
请参阅 LINQ / IEnumerable“包含”或“任何”作为开始。 你会想要 Linq,但更喜欢Intersect
形式为 ListA = ListA.Intersect(ListB)
请参阅 docs.microsoft.com/en-us/dotnet/csharp/programming-guide/…
【参考方案1】:
这是一种方法。
对于activeChunks
中在chunks
中找不到的块,以下代码会将Active
更改为false。
我假设:
两个列表中的块都有一个Id
属性
activeChunks
和 Active==false
中没有您想要保留的块。
var chunksInActiveChunksThatDontExistInChunks =
activechunks.Where( ch => !chunks.Any( ch => ch.Id == chunk.Id ));
// Since it seems you're not familiar with Linq
// please be aware that this will not be evaluated until foreach is executed
// You can evaluate it earlier by calling ToList()
// e.g. var chunksIn... = activechunks.Where(...).ToList();
foreach( var chunk in chunksInActiveChunksThatDontExistInChunks )
chunk.Active = false;
activeChunks.RemoveAll(x => x.Active == false);
如果您的对象匹配,您可以使用Contains
,但我不知道他们是否这样做,所以我选择了.Id
。可能是:
var chunksInActiveChunksThatDontExistInChunks =
activechunks.Where( ch => !chunks.Contains(ch));
对于
//删除“块”中不存在的块后,将块中不存在的块添加到ActiveChunks中
你可以:
var chunksThatAreInChunksButNotInActiveChunks =
chunks.Where( ch => !activeChunks.Any( ch => ch.Id == chunk.Id ));
activeChunks.AddRange(chunksThatAreInChunksButNotInActiveChunks);
请注意,如果列表在执行过程中被其他人修改,这不好。
【讨论】:
“ch”代表什么? + 块没有“Id” 在此上下文中,ch
代表 activechunks
中当前正在 Linq 操作中处理的元素 (Where
)。
activechunks.Except(chunks)
能否包含 Chunk 的声明?如果理解如何比较它们可能很重要,正如@tymtam 在这里指出的那样,他必须假设如何比较两个块。【参考方案2】:
var missing = ActiveChunks.Where(i => !chunks.Contains(i));
missing.ToList().ForEach(i => Console.WriteLine(i));
var activeMinusMissing = ActiveChunks.Where(i => missing.Contains(i));
ActiveChunks = activeMinusMissing;
missing
是一个列表,其中包含 ActiveChunks
中但在 chunks
中缺失的项目(例如,您要删除的项目)
Console.WriteLine()
可以是您喜欢的任何函数,它在要删除的每个项目上运行
activeMinusMissing
是一个列表,其中包含来自 ActiveChunks
的项目减去要删除的项目(例如 ActiveChunks 中但不在块中的项目)。
您可以将ActiveChunks
替换为activeMinusMissing
,而不是从ActiveChunks
中删除项目。
activeMinusMissing
变量仅用于演示,因此您可以将最后两行替换为
ActiveChunks= ActiveChunks.Where(i => missing.Contains(i)).ToList();
所以最终的代码是
var missing = ActiveChunks.Where(i => !chunks.Contains(i));
missing.ToList().ForEach(i => Console.WriteLine(i));
ActiveChunks= ActiveChunks.Where(i => missing.Contains(i)).ToList();
【讨论】:
【参考方案3】:根据您的代码,我认为,activechunks 最终是相同的块。无需添加和删除元素。移除所有 activechunks 元素并将所有 chunks 的元素添加到 activechunks 中。
【讨论】:
如果activeChunks
包含chunks
没有的元素怎么办?
嗯..你是对的。对不起。
而且我需要能够在删除之前停用该块。以上是关于从一个列表中删除元素如果不包含在另一个列表中。 C# [重复]的主要内容,如果未能解决你的问题,请参考以下文章
EF CORE PostgreSQL - 检查列表的所有元素是不是包含在另一个列表中