LINQ:比较两个列表并计算子集
LINQ: Compare two lists and count subset
我正在比较 2 个列表,我需要从主列表 (allModules) 中收集一个子集 (modulesToDelete) 的出现,仅当发现不止一次出现时。 (allModules 包含 modulesToDelete)。 modulesToDelete 中任何模块的多次出现意味着这些模块正在共享。在 modulesToDelete 中出现一个模块意味着该模块是隔离的并且可以安全删除(它只是找到了自己)。我可以使用嵌套的 foreach 循环来做到这一点,但这是我使用 LINQ 表达式(不起作用)收集的范围:
List<Module> modulesToDelete = { A, B, C, K }
List<string> allModules = {R, A, B, C, K, D, G, T, B, K } // need to flag B and K
var mods = from mod in modulesToDelete
where allModules.Any(name => name.Contains(mod.Name) && mod.Name.Count() > 1)
select mod;
这是我想用 LINQ 表达式替换的嵌套 foreach 循环:
foreach (Module mod in modulesToDelete)
{
int count = 0;
foreach (string modInAllMods in allModules)
{
if (modInAllMods == mod.Name)
{
count++;
}
}
if (count > 1)
{
m_moduleMarkedForKeep.Add(mod);
}
else if( count == 1)
{
// Delete the linked modules
}
}
您可以使用类似于字典但允许多个相等键和 returns 一个 IEnumerable<T>
作为值的查找。
var nameLookup = modulesToDelete.ToLookup(m => m.Name);
var safeToDelete = modulesToDelete.Where(m => nameLookup[m.Name].Count() == 1);
var sharedModules = modulesToDelete.Where(m => nameLookup[m.Name].Count() > 1);
编辑:但是,我根本看不出 allModules
有何关联。
可能更容易,并且在您的样本数据上得到预期的结果:
var mods = modulesToDelete.Where(m => allModules.Count(s => s == m.Name) > 1);
解决这个问题的一种方法是使用相交函数,
Intersection of two string array (ignore case)
我正在比较 2 个列表,我需要从主列表 (allModules) 中收集一个子集 (modulesToDelete) 的出现,仅当发现不止一次出现时。 (allModules 包含 modulesToDelete)。 modulesToDelete 中任何模块的多次出现意味着这些模块正在共享。在 modulesToDelete 中出现一个模块意味着该模块是隔离的并且可以安全删除(它只是找到了自己)。我可以使用嵌套的 foreach 循环来做到这一点,但这是我使用 LINQ 表达式(不起作用)收集的范围:
List<Module> modulesToDelete = { A, B, C, K }
List<string> allModules = {R, A, B, C, K, D, G, T, B, K } // need to flag B and K
var mods = from mod in modulesToDelete
where allModules.Any(name => name.Contains(mod.Name) && mod.Name.Count() > 1)
select mod;
这是我想用 LINQ 表达式替换的嵌套 foreach 循环:
foreach (Module mod in modulesToDelete)
{
int count = 0;
foreach (string modInAllMods in allModules)
{
if (modInAllMods == mod.Name)
{
count++;
}
}
if (count > 1)
{
m_moduleMarkedForKeep.Add(mod);
}
else if( count == 1)
{
// Delete the linked modules
}
}
您可以使用类似于字典但允许多个相等键和 returns 一个 IEnumerable<T>
作为值的查找。
var nameLookup = modulesToDelete.ToLookup(m => m.Name);
var safeToDelete = modulesToDelete.Where(m => nameLookup[m.Name].Count() == 1);
var sharedModules = modulesToDelete.Where(m => nameLookup[m.Name].Count() > 1);
编辑:但是,我根本看不出 allModules
有何关联。
可能更容易,并且在您的样本数据上得到预期的结果:
var mods = modulesToDelete.Where(m => allModules.Count(s => s == m.Name) > 1);
解决这个问题的一种方法是使用相交函数, Intersection of two string array (ignore case)