1

What is the best fastest way to Synchronize 2 Lists?

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>();

Each group has different number of members. How can i find out the different and merge both in one new list?

PS: I can change the type from IList to whatever if it would be more efficient.

Thanks

4

5 回答 5

7

所以首先我们需要一种有效的方法来比较这些对象。由于默认值EqualsGetHashCode实现在您的上下文中没有用,您要么需要覆盖它们,要么创建一个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();

这将包含任一列表中的所有用户组,但没有任何重复项。

于 2013-04-30T15:22:40.803 回答
1

你可以试试:

userGroup1.Concat(userGroup2).Distinct();

并且不要忘记为 UserGroup 类覆盖 Equals 和 GetHashCode。

于 2013-04-30T15:18:48.013 回答
0

您可以使用 HashSet 请参阅以下链接类http://msdn.microsoft.com/en-us/library/bb383091.aspx

于 2013-04-30T15:22:26.960 回答
0

请参阅此问题的答案:使用 linq 从两个对象列表创建列表

基本上你可以在System.Linq

userGroup1.Union(userGroup2).ToList();

于 2013-04-30T15:18:52.060 回答
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);
于 2018-11-09T15:19:12.743 回答