Is there an AddUnique method similar to Addrange() for alist in C#

前端 未结 9 1509
[愿得一人]
[愿得一人] 2021-01-07 16:32

I have a list in C#:

       var list = new List();
       list.AddRange(GetGreenCars());
       list.AddRange(GetBigCars());
       list.AddRange(         


        
相关标签:
9条回答
  • 2021-01-07 16:47

    Linq-less option! A different option in case the programmer cannot, or don't wanna use Linq.

    var list = new List<Car>();
    list.AddRange(GetGreenCars().FindAll((x) => !list.Contains(x)));
    list.AddRange(GetBigCars().FindAll((x) => !list.Contains(x)));
    list.AddRange(GetSmallCars().FindAll((x) => !list.Contains(x)));
    

    If the initial list is empty as in the example above, you can actually avoid using FindAll(...) on the first AddRange().

    0 讨论(0)
  • 2021-01-07 16:47

    and if you want to compare one property (id in this case), this should work

    var list = new List<string>();
    list.AddRange(GetGreenCars().Where(greencar => !list.Contains(greencar, car => car.id == greencar.id)));
    list.AddRange(GetBigCars().Where(bigcar => !list.Contains(bigcar, car => car.id == bigcar.id)));
    list.AddRange(GetSmallCars().Where(smallcar => !list.Contains(smallcar, car => car.id == smallcar.id)));
    
    0 讨论(0)
  • 2021-01-07 16:48

    Yet another option using Linq:

    public static void AddUnique<T>(this IList<T> self, IEnumerable<T> items)
    {
      self.AddRange(
        items.Where(x => self.FirstOrDefault(y => y.Name == x.Name) ==
        null).ToList());
    }
    
    var list = new List<Car>();
    list.AddUnique(GetGreenCars());
    list.AddUnique(GetBigCars());
    list.AddUnique(GetSmallCars());
    
    0 讨论(0)
  • 2021-01-07 16:49

    I created an extension method that adds only unique values to anything implementing ICollection<T> (including a List<T>) from an IEnumerable<T>. Unlike implementations that use List<T>.Contains(), this method allows you to specify a lambda expression that determines if two items are the same.

    /// <summary>
    /// Adds only items that do not exist in source.  May be very slow for large collections and some types of source.
    /// </summary>
    /// <typeparam name="T">Type in the collection.</typeparam>
    /// <param name="source">Source collection</param>
    /// <param name="predicate">Predicate to determine whether a new item is already in source.</param>
    /// <param name="items">New items.</param>
    public static void AddUniqueBy<T>(this ICollection<T> source, Func<T, T, bool> predicate, IEnumerable<T> items)
    {
        foreach (T item in items)
        {
            bool existsInSource = source.Where(s => predicate(s, item)).Any();
            if (!existsInSource) source.Add(item);
        }
    }
    

    Usage:

    source.AddUniqueBy<Foo>((s, i) => s.Id == i.Id, items);
    
    0 讨论(0)
  • 2021-01-07 17:03

    Another option is to do something like:

    public static void AddUnique<T>( this IList<T> self, IEnumerable<T> items )
    {
        foreach(var item in items)
            if(!self.Contains(item))
                self.Add(item);
    }
    
    
    var list = new List<Car>();
    list.AddUnique(GetGreenCars());
    list.AddUnique(GetBigCars());
    list.AddUnique(GetSmallCars());
    
    0 讨论(0)
  • 2021-01-07 17:04

    One choice is to add them and remove the repeated ones:

    var list = new List<Car>();
    list.AddRange(GetGreenCars());
    list.AddRange(GetBigCars());
    list.AddRange(GetSmallCars());
    list = list.Distinct().ToList();
    
    0 讨论(0)
提交回复
热议问题