【问题标题】:Cross join of unknown number of string arrays using linq使用 linq 交叉连接未知数量的字符串数组
【发布时间】:2018-08-19 19:26:07
【问题描述】:

是否可以使用 linq 在事先不知道连接数量的情况下进行交叉连接?

我有这个:

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

如果我知道我可以做三个列表:

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

是否可以使用 linq 加入 n 字符串数组?

【问题讨论】:

标签: c# linq cross-join


【解决方案1】:

请尝试以下解决方案以获得给定“N”个字符串数组的笛卡尔积。

    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());
        }
}

【讨论】:

    【解决方案2】:

    尝试this solution,其中result 中的每个item 看起来都不会像{x:"A", y:"B", ... },因为无法预测属性的数量,所以它会像["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])));
    

    【讨论】:

      【解决方案3】:
              [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;
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-02-05
        • 1970-01-01
        • 1970-01-01
        • 2021-08-04
        • 2010-09-12
        • 2022-08-18
        • 1970-01-01
        相关资源
        最近更新 更多