Объединение двух списков объектов, но удаление дубликатов на основе разных значений

Для семейства Debian / Ubuntu мы обычно рекомендуем

 $ sudo apt-get install r-base-dev

, поскольку он извлекает все пакеты, которые обычно необходимы для компиляции. И этот подход все время тестируется, так как на это полагаются автоматизированные разработчики пакетов (а также дополнительные встроенные сборки для каждого пакета). Пакет gfortran также указан здесь; возможно, у вас есть неработающая ссылка из предыдущей установки, поэтому я также попробую dpkg --purge gfortran; apt-get install gfortran. Тем не менее, десятки пакетов R (и самого R) используют Fortran, поэтому здесь не должно быть никакой магии.

0
задан Robbert Raats 18 March 2019 в 15:15
поделиться

3 ответа

Вы можете использовать System.Linq методы расширения Union (чтобы получить объединение двух списков) вместе с Where и All, чтобы отфильтровать элементы, которые вы не хотите включать в первый список: [ 1113]

var result = list2.Union(list1.Where(l1 => list2.All(l2 => l2.ParentId != l1.Id)));

Но обратите внимание, что Union будет использовать метод Equals класса, чтобы определить, совпадают ли два элемента (который по умолчанию является эталонным сравнением), поэтому вам придется переопределить Equals и GetHashCode для удаления дубликатов (где дубликат будет определен вами, в этом случае, я думаю, будет определено, где совпадают свойства Id двух элементов, но, возможно, вы также включите ParentId).

Например:

public class Item
{
    public int Id { get; set; }
    public int? ParentId { get; set; }

    public override int GetHashCode()
    {
        return Id.GetHashCode();
    }

    public override bool Equals(object obj)
    {
        return Id == (obj as Item)?.Id;
    }
}

И тогда пример использования будет:

public class Program
{
    private static void Main(string[] args)
    {
        var list1 = new List<Item>
        {
            new Item {Id = 1, ParentId = null},
            new Item {Id = 2, ParentId = null},
            new Item {Id = 3, ParentId = 1}
        };

        var list2 = new List<Item>
        {
            new Item {Id = 3, ParentId = 1}
        };

        var result = list2.Union(list1.Where(l1 => list2.All(l2 => l2.ParentId != l1.Id)));

        GetKeyFromUser("\nDone! Press any key to exit...");
    }
}
0
ответ дан Rufus L 18 March 2019 в 15:15
поделиться

Вы можете попытаться найти первое совпадение ParentId из List2 при итерации List1 и добавить в зависимости от того, был ли он найден:

var UnionList = new List<Item>();
foreach (var item in List1)
{
    var match = List2.FirstOrDefault(x => x.ParentId == item.Id);
    resultList.Add(match ?? item);
}

Или только с LINQ:

var UnionList = new List<Item>(List1.Select(item => List2.FirstOrDefault(x => x.ParentId == item.Id) ?? item));
0
ответ дан RoadRunner 18 March 2019 в 15:15
поделиться

Я думаю, что я получил то, что вы хотите - вы хотите, чтобы не выдавать ни одного идентификатора дважды. Таким образом, если в поле «родитель» используется какой-либо «родитель», то в этом случае вы не хотите использовать его дополнительно?

в этом случае вы можете сделать это:

var result = List1.Where(x => !List2.Any(l2 => l2.parentId == x.id)).Union(List2);//.ToList();

Часть Где исключает все элементы, которые используются в качестве родителей в List2. И, с Union (исключая дубликаты), он объединяет List2. ToList () может быть необязательным, в зависимости от того, что вы будете делать с ним дальше.

РЕДАКТИРОВАТЬ: изменена форма Concat на Union.

0
ответ дан Malior 18 March 2019 в 15:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: