Cross joining an unknown number of string arrays using linq

Is it possible to cross-connect using linq, where the number of connections is not known in advance?

I have it:

var arrays = new List<string[]>();

If I know, I have three lists that I can do:

var oQuery = from x in arrays[0]
    from y in arrays[1]
    from z in arrays[2]
    select new {x, y, z};

Is it possible to link arrays of strings nusing linq?

+4
source share
3 answers

Please try the solution below to get the Cartesian product for a given number N lines of arrays.

    static void Main(string[] args)
    {

        var arrays = new List<string[]>();
        var arr1 = new string[] { "A", "B", "C" };
        var arr2 = new string[] { "D", "E", "F" };
        var arr3 = new string[] { "G", "H", "I" };
        arrays.Add(arr1);
        arrays.Add(arr2);
        arrays.Add(arr3);

        IEnumerable<Tuple<string,string>> oQuery1 = null;
        int count = arrays.Count;
        var k = arrays[0].AsEnumerable();
        for (int i =1; i< count; i++)
        {
            var l1 = arrays[i];

            oQuery1 =  k.SelectMany((x) => l1, (x, y) => Tuple.Create( x, y ));
            k = oQuery1.Select(x=>x.ToString());
        }
}
+1
source

Try this solution , each itemof resultnot going to look like {x:"A", y:"B", ... }, because the number of properties is not predicted, so instead it will be like ["A", "B", ... ]:

public static List<List<string>> CrossJoin(List<string[]> arrays)
{
    var data = arrays.Select(x => x.ToList()).ToList();
    List<List<string>> result = data[0].Select(x => new List<string> { x }).ToList();

    for (var i = 1; i < data.Count; i++)
        result = (from a in result
                  from b in data[i]
                  select new { a, b })
                  .Select(x => x.a.Concat(new List<string> { x.b }).ToList())
                  .ToList();

    return result;
}

:

var arr1 = new[] { "A", "B", "C" };
var arr2 = new[] { "D", "E" };
var arr3 = new[] { "F", "G" };

var result = CrossJoin(new List<string[]> { arr1, arr2, arr3 });
for(var i = 0; i < result.Count; i++) 
    Console.WriteLine(string.Format("{0}: {1}", i + 1, string.Join(",", result[i])));
+1
        [Fact]
    public void Test1()
    {
        var listOfStringList = new List<List<string>>();
        var list1 = new List<string> { "A", "B", "C" };
        var list2 = new List<string> { "AA", "BB", "CC" };
        var list3 = new List<string> { "AAA", "BBB", "CCC" };
        listOfStringList.Add(list1);
        listOfStringList.Add(list2);
        listOfStringList.Add(list3);
        var resultData = new List<List<string>>();
        listOfStringList.ForEach((stringList) =>
        {
            if (resultData.Count == 0)
            {
                resultData = stringList.Select(u => new List<string> { u }).ToList();
                return;
            }
            resultData = resultData.SelectMany(u => stringList
                .Select(v =>
                {
                    var list = new List<string>();
                    u.ForEach(sv =>
                    {
                        list.Add(sv);
                    });
                    list.Add(v);
                    return list;
                }).ToList()).ToList();
        });
        // Ignore variable resultantData it is just for highlight
        var resultantData = resultData;
    }
0

Source: https://habr.com/ru/post/1694742/


All Articles