比较两个列表中的项目并用 LINQ 替换 foreach 循环
Compare items in two lists and replace foreach loop with LINQ
我有两个列表:
List<Item1> list1;
List<Item2> list2;
我有以下代码用于比较列表中的项目:
ConcurrentDictionary<string, string> compareDictionary = new ConcurrentDictionary<string, string>();
for (int i = 0; i < lis1.Count; i++)
{
var item1Name= list1[i].Name.ToString();
var item1Id= list1[i].ID.ToString();
foreach (var item in list2)
{
if (item1Name.Contains(item.item2Name.ToLower()))
{
compareDictionary.TryAdd(item1Id, item.item2Id);
}
}
}
需要将第一个列表的 Id
和第二个列表的 Id
添加到 ConcurrentDictionary,如果一个项目的 Name
包含另一个项目的一部分。
它有效,但我想简化算法并删除 foreach
和 if
.
您可以使用 System.Linq 摆脱内部循环。还通过使用 foreach 代替主循环的 for 来简化代码:
ConcurrentDictionary<string, string> compareDictionary = new ConcurrentDictionary<string, string>();
foreach (var element in list1)
{
var item1Name= element.Name.ToString();
var item1Id= element.ID.ToString();
// If this element has already one correspondence, TryAdd will fail anyway
if(compareDictionary.ContainsKey(item1Id)) continue;
var found = list2.FirstOrDefault(item => item1Name.Contains(item.item2Name.ToLower()));
if(found != null)
{
compareDictionary.TryAdd(item1Id, item.item2Id);
}
}
根据您的元素命名,您可能还需要将 item1Name 设为小写。
你的代码实际上会找到这个对应关系:
Parentwithlittlechild --> LittleChild
但不是这个:
ParentWithLittleChild --> LittleChild
因为 "LittleChild" 会小写,而 String.Contains 默认情况下区分大小写。
您还可以将 IndexOf
方法与 StringComparison.OrdinalIgnoreCase
一起使用,如下所示:
var found = list2.FirstOrDefault(item => item1Name.IndexOf(item.item2Name, StringComparison.OrdinalIgnoreCase) >= 0);
最终考虑:element.Name
可能已经是字符串类型,除非您的 Item1.Name
属性 是某种有趣的类型。如果是这样,element.Name.ToString()
只需 element.Name
.
即可转换
几个代码片段,用于查找匹配项并将两个对象的 ids
添加到 ConcurrentDictionary<string, string>
。
所以我们有:
var dict = new ConcurrentDictionary<string, string>();
第一
list1.ForEach(x =>
{
list2.Where(y => y.Item2Name.IndexOf(x.Name, StringComparison.CurrentCultureIgnoreCase) >= 0)
.ToList().ForEach(y => dict.TryAdd(x.ID, y.Item2Id));
});
第二
(from x in list1
from y in list2
where x.Name.IndexOf(y.Item2Name, StringComparison.CurrentCultureIgnoreCase) >= 0
select (x, y)).ToList().ForEach(item => dict.TryAdd(item.x.ID, item.y.Item2Id));
旁注
如果Item1.Name
和Item2.Item2Name
属性都是string
类型,那么就不需要像[=20=那样使用ToString()
函数]行。
如果Item1.ID
和Item2.Item2Id
属性都是int
类型,那么Key
和Value
的正确类型双字典是int
类型。所以:
var dict = new ConcurrentDictionary<int, int>();
我有两个列表:
List<Item1> list1;
List<Item2> list2;
我有以下代码用于比较列表中的项目:
ConcurrentDictionary<string, string> compareDictionary = new ConcurrentDictionary<string, string>();
for (int i = 0; i < lis1.Count; i++)
{
var item1Name= list1[i].Name.ToString();
var item1Id= list1[i].ID.ToString();
foreach (var item in list2)
{
if (item1Name.Contains(item.item2Name.ToLower()))
{
compareDictionary.TryAdd(item1Id, item.item2Id);
}
}
}
需要将第一个列表的 Id
和第二个列表的 Id
添加到 ConcurrentDictionary,如果一个项目的 Name
包含另一个项目的一部分。
它有效,但我想简化算法并删除 foreach
和 if
.
您可以使用 System.Linq 摆脱内部循环。还通过使用 foreach 代替主循环的 for 来简化代码:
ConcurrentDictionary<string, string> compareDictionary = new ConcurrentDictionary<string, string>();
foreach (var element in list1)
{
var item1Name= element.Name.ToString();
var item1Id= element.ID.ToString();
// If this element has already one correspondence, TryAdd will fail anyway
if(compareDictionary.ContainsKey(item1Id)) continue;
var found = list2.FirstOrDefault(item => item1Name.Contains(item.item2Name.ToLower()));
if(found != null)
{
compareDictionary.TryAdd(item1Id, item.item2Id);
}
}
根据您的元素命名,您可能还需要将 item1Name 设为小写。 你的代码实际上会找到这个对应关系:
Parentwithlittlechild --> LittleChild
但不是这个:
ParentWithLittleChild --> LittleChild
因为 "LittleChild" 会小写,而 String.Contains 默认情况下区分大小写。
您还可以将 IndexOf
方法与 StringComparison.OrdinalIgnoreCase
一起使用,如下所示:
var found = list2.FirstOrDefault(item => item1Name.IndexOf(item.item2Name, StringComparison.OrdinalIgnoreCase) >= 0);
最终考虑:element.Name
可能已经是字符串类型,除非您的 Item1.Name
属性 是某种有趣的类型。如果是这样,element.Name.ToString()
只需 element.Name
.
几个代码片段,用于查找匹配项并将两个对象的 ids
添加到 ConcurrentDictionary<string, string>
。
所以我们有:
var dict = new ConcurrentDictionary<string, string>();
第一
list1.ForEach(x =>
{
list2.Where(y => y.Item2Name.IndexOf(x.Name, StringComparison.CurrentCultureIgnoreCase) >= 0)
.ToList().ForEach(y => dict.TryAdd(x.ID, y.Item2Id));
});
第二
(from x in list1
from y in list2
where x.Name.IndexOf(y.Item2Name, StringComparison.CurrentCultureIgnoreCase) >= 0
select (x, y)).ToList().ForEach(item => dict.TryAdd(item.x.ID, item.y.Item2Id));
旁注
如果
Item1.Name
和Item2.Item2Name
属性都是string
类型,那么就不需要像[=20=那样使用ToString()
函数]行。如果
Item1.ID
和Item2.Item2Id
属性都是int
类型,那么Key
和Value
的正确类型双字典是int
类型。所以:
var dict = new ConcurrentDictionary<int, int>();