同步2个列表的最快方法是什么?
public class UserGroup
{
public UserGroup(string group, string user)
{
this.Group = group;
this.User = user;
}
public string Group { get; set; }
public string User { get; set; }
}
IList<UserGroup> userGroup1 = new IList<UserGroup>();
IList<UserGroup> userGroup2 = new IList<UserGroup>();
每个小组的成员数量不同。 我怎样才能找到不同的并将它们合并到一个新列表中?
PS:我可以将类型从IList更改为任何更高效的类型。
由于
答案 0 :(得分:6)
首先,我们需要一种比较这些对象的有效方法。由于默认的Equals
和GetHashCode
实现在您的上下文中没有用,您需要覆盖它们,或创建IEqualityComparer
。我做了后者,如果你愿意,你可以随意做前者。这是一个简单的比较器:
public class UserGroupComparer : IEqualityComparer<UserGroup>
{
public bool Equals(UserGroup x, UserGroup y)
{
return x.Group == y.Group && x.User == y.User;
}
public int GetHashCode(UserGroup obj)
{
return 37 * obj.Group.GetHashCode() + 19 * obj.User.GetHashCode();
}
}
现在您已拥有此比较器,您可以利用LINQ为您完成工作:
var combinedList = userGroup1.Union(userGroup2, new UserGroupComparer())
.ToList();
这将包含列表中的所有用户组,但没有任何重复项。
答案 1 :(得分:1)
您可以尝试:
userGroup1.Concat(userGroup2).Distinct();
不要忘记为UserGroup类重写Equals和GetHashCode。
答案 2 :(得分:0)
请参阅此问题的答案:Create a list from two object lists with linq
基本上你可以在System.Linq
:
userGroup1.Union(userGroup2).ToList();
答案 3 :(得分:0)
您可以使用HashSet,请参阅以下链接类http://msdn.microsoft.com/en-us/library/bb383091.aspx
答案 4 :(得分:0)
如果集合中的项目属于两种不同类型,则可以使用以下内容:
class CollectionSynchronizer<TSource, TDestination>
{
public Func<TSource, TDestination, bool> CompareFunc { get; set; }
public Action<TDestination> RemoveAction { get; set; }
public Action<TSource> AddAction { get; set; }
public Action<TSource, TDestination> UpdateAction { get; set; }
public void Synchronizer(ICollection<TSource> sourceItems, ICollection<TDestination> destinationItems)
{
// Remove items not in source from destination
RemoveItems(sourceItems, destinationItems);
// Add items in source to destination
AddOrUpdateItems(sourceItems, destinationItems);
}
private void RemoveItems(ICollection<TSource> sourceCollection, ICollection<TDestination> destinationCollection)
{
foreach (var destinationItem in destinationCollection.ToArray())
{
var sourceItem = sourceCollection.FirstOrDefault(item => CompareFunc(item, destinationItem));
if (sourceItem == null)
{
RemoveAction(destinationItem);
}
}
}
private void AddOrUpdateItems(ICollection<TSource> sourceCollection, ICollection<TDestination> destinationCollection)
{
var destinationList = destinationCollection.ToList();
foreach (var sourceItem in sourceCollection)
{
var destinationItem = destinationList.FirstOrDefault(item => CompareFunc(sourceItem, item));
if (destinationItem == null)
{
AddAction(sourceItem);
}
else
{
UpdateAction(sourceItem, destinationItem);
}
}
}
}
用法如下:
var collectionSynchronizer = new CollectionSynchronizer<string, ContentImageEntity>
{
CompareFunc = (communityImage, contentImage) => communityImage == contentImage.Name,
AddAction = sourceItem =>
{
var contentEntityImage = _contentImageProvider.Create(sourceItem);
contentEntityImages.Add(contentEntityImage);
},
UpdateAction = (communityImage, contentImage) =>
{
_contentImageProvider.Update(contentImage);
},
RemoveAction = contentImage =>
{
contentEntityImages.Remove(contentImage);
}
};
collectionSynchronizer.Synchronizer(externalContentImages, contentEntityImages);