C# LINQ Zipping 2 списка списков на основе уникальности объектов - PullRequest
0 голосов
/ 17 февраля 2020

Я пытаюсь сжать 2 списка списков объектов - только там, где результирующий сжатый список будет содержать списки различных объектов (списки списка 2 иногда имеют дублирующиеся объекты по сравнению со списком 1). Количество объектов в результирующем списке должно быть сохранено, то есть у нас не может быть списков разных размеров. Количество списков в списке 1 больше числа в списке 2. Это означало бы многократное прохождение списка 2 при архивировании.

Вышеприведенное представлено с использованием циклов ниже. Возможно ли это, используя только linq?

//this list of list contains the larger number of elements to which the 2nd list of list needs to be joined
List<List<object>> FullList = new List<List<object>>(); //is not empty - instantiated with some list

//2nd list of list - contains duplicates of the 1st list in terms of the objects in the underlying list
List<List<object>> comboBaseList = new List<List<object>>(); //is not empty - instantiated with some list
List<List<object>> comboList = comboBaseList;

//need to zip lists where there are no duplicate objects in the 2nd list's list, the count of the 1st list of list remains the same as FullList
List<List<object>> finalList = new List<List<object>>(); //empty - meant to hold final combined list

int i = 0;

foreach iList in FullList
{
    if (i < comboList.count)
    {
        while (iList.Select(x => x.Id).Contains(comboList[i].Select(y => y.Id)))
        {
            i += 1;
        }
        finalList.Add(iList.Zip(comboList[i], (x, y) => x.Union(y))); //**CAN WE BYPASS THE LOOPS AND JUST USE LINQ?
        comboList.RemoveAt(i);
        i = 0;
    }
    else
    {
        comboList = comboBaseList;
        i = 0;
    }
}

Чтобы упростить данные, я буду использовать списки списков целых чисел, которые могут быть идентификаторами объектов в моем случае

FullList = 
(
{1,2,3},
{2,5,6},
{7,8,9}
)

comboList = 
(
{2,5},
{8,9}
)

Я хочу сжать вышеупомянутые списки, чтобы получить результирующий результат, как показано ниже. Обратите внимание, что в FullList есть 3 результата, а в нижележащих списках есть различные целые числа

finalList =
{
 {1,2,3,8,9},
 {2,5,6,8,9},
 {7,8,9,2,5}
}

Ответы [ 2 ]

1 голос
/ 17 февраля 2020

Хорошо, это звучит так, как если бы вы хотели что-то вроде:

var result = fullList
    .Select(original =>
       // We want the original sublist...
       original
           // concatenated with...
           .Concat(
           // ... any comboList element
           comboList
               // which is completely distinct from "original"
               .Where(cl => !original.Intersect(cl).Any())
               // ... flattening all such comboLists
               .SelectMany(cl => cl))
           .ToList())
    .ToList();

Вот полный пример:

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main()
    {
        var fullList = new[]
        {
            new[] { 1, 2, 3 },
            new[] { 2, 5, 6 },
            new[] { 7, 8, 9 }
        };

        var comboList = new[]
        {
            new[] { 2, 5 },
            new[] { 8, 9 }
        };

        var result = MergeCombinations(fullList, comboList);
        foreach (var item in result)
        {
            Console.WriteLine(string.Join(", ", item));
        }
    }

    static List<List<T>> MergeCombinations<T>(
        IEnumerable<IEnumerable<T>> fullList,
        IEnumerable<IEnumerable<T>> comboList)
    {
        var result = fullList
            .Select(original =>
                // We want the original sublist...
                original
                    // concatenated with...
                    .Concat(
                    // ... any comboList element
                       comboList
                           // which is completely distinct from "original"
                           .Where(cl => !original.Intersect(cl).Any())
                           // ... flattening all such comboLists
                          .SelectMany(cl => cl))
                   .ToList())
             .ToList();
        return result;
    }                                           
}
0 голосов
/ 17 февраля 2020
var fullList = new List<List<int>>()
        {
            new List<int>() {1,2,3},
            new List<int>() {2,5,6},
            new List<int>() {7,8,9}
        };

 var comboList = new List<List<int>>()
        {
            new List<int>() {2,5},
            new List<int>() {8,9},
        };


fullList.ForEach(i =>
        {
            comboList.ForEach(j =>
            {
                if (i.All(x => !j.Contains(x)))
                {
                    i.AddRange(j);
                    return;
                };
            });
        });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...