Слияние пары ключ-значение List при удалении дубликатов C # - PullRequest
0 голосов
/ 24 мая 2018
var a1 = new List<KeyValuePair<TKey, TValue>>();
var a2 = new List<KeyValuePair<TKey, TValue>>();

У меня есть два приведенных выше списка пар ключ-значение.Я хочу объединить их при удалении дубликатов.Я почти уверен, что могу сделать это с помощью LINQ, но примеры, которые я видел, не применяются напрямую, потому что они не определяют полный процесс от List<KeyValuePair<TKey, TValue>> до List<KeyValuePair<TKey, TValue>>.Если два списка содержат один и тот же ключ, они также будут иметь одинаковое значение, поэтому не имеет значения, какой из них будет сохранен при объединении.

Ответы [ 4 ]

0 голосов
/ 24 мая 2018

Что делать, если вы создаете словарь, перебираете два списка и добавляете их в словарь?В словаре не может быть идентичного ключа, поэтому используйте попытку try при попытке добавить.

Dictionary<TKey,TValue> myDictionary = new Dictionary();

//Iterate over list
//add try catch to attempt to add key and value to the dictionary.
0 голосов
/ 24 мая 2018

Если (как указано) вы не возражаете против того, какой из дубликатов выбран, то:

var result = a1.Concat(a2)
               .GroupBy(x => x.Key)
               .Select(g => g.First())
               .ToList();

или, если у вас много предметов, лучшим способом было бы использовать (более эффективно) DistinctBy реализация.Это (более или менее) из MoreLinq .

public static class LinqEx
{
    public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source,
        Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer = null)
    {
        if (source == null) throw new ArgumentNullException(nameof(source));
        if (keySelector == null) throw new ArgumentNullException(nameof(keySelector));

        return _(); IEnumerable<TSource> _()
        {
            var knownKeys = new HashSet<TKey>(comparer);
            foreach (var element in source)
            {
                if (knownKeys.Add(keySelector(element)))
                    yield return element;
            }
        }

    }
}

затем

var result = a1.Concat(a2)
               .DistinctBy(x => x.Key)
               .ToList();
0 голосов
/ 24 мая 2018

Предполагая, что «два списка содержат один и тот же ключ, они также будут иметь одинаковое значение». Вы можете сделать это:

var a3 = new List<KeyValuePair<TKey, TValue>>();
a3.AddRange(a1);
a3.AddRange(a2);
var a3 = a3.Distinct().ToList();

или:

var a3 = a1.Union(a2).ToList();
0 голосов
/ 24 мая 2018

Вы правы, вы можете сделать это в Linq.Тем не менее, вы должны быть осторожны с тем, как равенство реализовано на вашем TValue (вы должны быть осторожны и на TKey, конечно, но вы сказали, что это были строки, так что равенство четко определено).

void Main()
{
    var a1 = new List<KeyValuePair<string, int>>();
    var a2 = new List<KeyValuePair<string, int>>();

    a1.Add(new KeyValuePair<string, int>("A", 1));
    a1.Add(new KeyValuePair<string, int>("B", 2));
    a1.Add(new KeyValuePair<string, int>("C", 3));
    a1.Add(new KeyValuePair<string, int>("D", 4));


    a2.Add(new KeyValuePair<string, int>("B", 2));
    a2.Add(new KeyValuePair<string, int>("E", 5));
    a2.Add(new KeyValuePair<string, int>("C", 33));

    var distinct = a1.Union(a2).Distinct();

    foreach(var kv in distinct)
    {
        Console.WriteLine($"{kv.Key}={kv.Value}");
    }
}

Будет напечатан следующий результат:

A=1
B=2
C=3
D=4
E=5
C=33
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...