简体   繁体   中英

How to Zip two Lists of different size to create a new list that is same as the size of the longest amongst the original lists?

I have two C# Lists of different sizes eg

List<int> list1 = new List<int>{1,2,3,4,5,6,7};
List<int> list2 = new List<int>{4,5,6,7,8,9};

I want to use the linq Zip method to combine these two into a list of tuples that is of the size list1. Here is the resulting list I am looking for

{(1,4), (2,5), (3,6), (4,7), (5,8), (6,9), (7,0)}  //this is of type List<(int,int)

Since the last item of list1 does not has a counterpart in list2, I fill up my last item of the resulting list with a default value (in this case 0 as in my case it will never appear in any of the original lists).

Is there a way I can use the linq Zip method alone to achieve this?

You can use Concat to make them both the same size, and then zip it:

var zipped = list1.Concat(Enumerable.Repeat(0,Math.Max(list2.Count-list1.Count,0)))
        .Zip(list2.Concat(Enumerable.Repeat(0,Math.Max(list1.Count-list2.Count,0))),
            (a,b)=>(a,b));

Or create an extension method:

public static class ZipExtension{
    public static IEnumerable<TResult> Zip<TFirst,TSecond,TResult>(
        this IEnumerable<TFirst> first,
        IEnumerable<TSecond> second, 
        Func<TFirst,TSecond,TResult> func, 
        TFirst padder1,
        TSecond padder2)
    {
        var firstExp = first.Concat(
            Enumerable.Repeat(
                padder1, 
                Math.Max(second.Count()-first.Count(),0)
            )
        );
        var secExp = second.Concat(
            Enumerable.Repeat(
                padder2,
                Math.Max(first.Count()-second.Count(),0)
            )
        );
        return firstExp.Zip(secExp, (a,b) => func(a,b));
    }
}

So you can use like this:

//last 2 arguments are the padder values for list1 and list2
var zipped = list1.Zip(list2, (a,b) => (a,b), 0, 0); 

Try this using Zip function-

static void Main(string[] args)
    {
        List<int> firstList = new List<int>() { 1, 2, 3, 4, 5, 6, 0, 34, 56, 23 };
        List<int> secondList = new List<int>() { 4, 5, 6, 7, 8, 9, 1 };

        int a = firstList.Count;
        int b = secondList.Count;

        for (int k = 0; k < (a - b); k++)
            {
                if(a>b)
                    secondList.Add(0);
                else
                    firstList.Add(0);
            }

        var zipArray = firstList.Zip(secondList, (c, d) => c + " " + d);
        foreach(var item in zipArray)
        {
            Console.WriteLine(item);
        }
        Console.Read();
    }

Or you can try this using ZipLongest Function by installing MoreLinq nuget package-

static void Main(string[] args)
    {
        List<int> firstList = new List<int>() { 1, 2, 3, 4, 5, 6, 0, 34, 56, 23 };
        List<int> secondList = new List<int>() { 4, 5, 6, 7, 8, 9, 1 };

        var zipArray = firstList.ZipLongest(secondList, (c, d) => (c,d));
        foreach (var item in zipArray)
        {
            Console.WriteLine(item);
        }
        Console.Read();
    }

Try this code-

static void Main(string[] args)
    {
        List<int> firstList=new List<int>() { 1, 2, 3, 4, 5, 6,0,34,56,23};
        List<int> secondList=new List<int>() { 4, 5, 6, 7, 8, 9,1};

        int a = firstList.Count;
        int b = secondList.Count;

        if (a > b)
        {
            for(int k=0;k<(a-b);k++)
                secondList.Add(0);
        }
        else
        {
            for (int k = 0; k < (b-a); k++)
                firstList.Add(0);
        }

        for(int i=0;i<firstList.Count;i++)
        {
            for(int j=0;j<=secondList.Count;j++)
            {
                if(i==j)
                    Console.Write($"({Convert.ToInt32(firstList[i])},{ Convert.ToInt32(secondList[j])})" + "");
            }
        }
        Console.Read();
    }

There is a useful and popular MoreLinq library. Install it and use.

using MoreLinq;
var result = list1.ZipLongest(list2, (x, y) => (x, y));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM