c#组合列表并将项目标记为已找到
本文关键字:记为 目标 项目 组合 列表 | 更新日期: 2023-09-27 18:02:44
我有一个类:
public class Item
{
public string Name { get; set; }
public bool IsFound { get; set; }
}
和2个列表:
List<Item> first = new List<Item>();
List<Item> second = new List<Item>();
First
列表包含一些预定义的唯一项目Second
列表还包含一些独特的项目
如何根据Name
属性将第二个列表项添加到第一个列表中而不重复,忽略大小写?
将second
中的项目添加到现有的first
列表中:
List<Item> first = new List<Item>();
List<Item> second = new List<Item>();
...
// ids to exclude while adding
HashSet<String> ids = new HashSet<string>(first.Select(item => item.Name),
StringComparer.InvariantCultureIgnoreCase);
// add all items from the second, except exluded
first.AddRange(second.Where(item => !ids.Contains(item.Name)));
这是一个使用HashSet`1
和IEquatable`1
的工作解决方案。如果你需要使用List`1
,你可以使用Ned Stoyanov的答案中指出的Linq。
代码:
class Program {
static void Main(string[] args) {
var first = new HashSet<Item>() {
new Item() { Name = "a" },
new Item() { Name = "b" },
};
var second = new HashSet<Item>() {
new Item() { Name = "b" },
new Item() { Name = "c" },
};
var both = first.Union(second).ToList();
both.ForEach(Console.WriteLine);
Console.ReadKey();
}
}
public class Item : IEquatable<Item> {
public string Name { get; set; }
public bool IsFound { get; set; }
public override bool Equals(object that) {
return that is Item && this.Equals((Item)that);
}
public bool Equals(Item that) {
return this.Name.Equals(that.Name, StringComparison.InvariantCultureIgnoreCase);
}
public override int GetHashCode() {
return Name.GetHashCode();
}
public override string ToString() {
return Name;
}
}
输出:
a
b
c
注意:由于HashSet`1
s的实现,元素的顺序不受尊重。
First.Union(Second).GroupBy(x=>x.Name).Select(x=>x.FirstOrDefault());
如果你事先知道你的列表有唯一的项目,为什么它们不是ISet<项目>?这正是ISet的用途。一旦您将它们更改为ISet,您可以简单地调用:
first.UnionWith(second);
如果您实现了IEqualityComparer<Item>
或更好的版本,请使用此答案中的KeyEqualityComparer
。您可以使用Linq Union
来获得您的结果。
first.Union(second, new KeyEqualityComparer( i => i.Name));
如果没有,我如何将第二个列表项添加到第一个列表是否基于Name属性重复,忽略大小写?
这是你想要的:
List<Item> third = first.Concat(second)
.GroupBy(i => i.Name, StringComparer.InvariantCultureIgnoreCase)
.Select(g => new Item
{
Name = g.Key,
IsFound = g.Count() > 1
})
.ToList();
g.Count() > 1
仅适用于来自不同列表的具有相同名称(忽略大小写(的项目,因此g.Count()
为1或2。
这应该做到:
var distinct = from item in second
where first.All(x => !String.Equals(x.Name, item.Name, StringComparison.OrdinalIgnoreCase))
select item;
first.AddRange(distinct);
您可以有一个组合列表,其中只添加第二个列表中缺少的项。
class Program
{
static void Main(string[] args)
{
var first = new List<Item> { new Item("one"), new Item("two") };
var second = new List<Item> { new Item("two"), new Item("three") };
var combined = new List<Item>();
combined.AddRange(first);
foreach (var item in second)
{
int index = combined.FindIndex(x => x.name == item.name);
if (index <= 0)
{
combined.Add(item);
}
}
foreach (var item in combined)
{
Console.WriteLine(item.name);
}
}
class Item
{
public string name;
public Item(string name)
{
this.name = name;
}
}
}