代码之家  ›  专栏  ›  技术社区  ›  Pikachu620

如何将多维数组转换为字典?

  •  4
  • Pikachu620  · 技术社区  · 6 年前

    我有一个n乘3的数组我想转换成 Dictionary<string,string[]> 其中第一列是键,其余列作为值的数组。

    例如:

    Key = arr[0,0], Value = new string[2] {arr[0,1], arr[0,2]}.
    

    我知道 ToDictionary 但我不知道如何设定价值部分。

    arr.ToDictionary(x=>arr[x,0],x=>new string[2]{arr[x,1],arr[x,2]});
    //This doesn't work!!!
    

    如何正确设置?

    5 回复  |  直到 6 年前
        1
  •  1
  •   MineR    6 年前

    有时不使用linq更容易阅读,速度更快:

     var dict = new Dictionary<string, string[]>();
     for (int i = 0; i < arr.GetLength(0); i++)
          dict[arr[i, 0]] = new string[] { arr[i, 1], arr[i, 2] };
    

    但当你觉得你真的需要使用linq时:

     Enumerable.Range(0, arr.GetLength(0))
         .ToDictionary(i => arr[i, 0], i => new string[] {arr[i, 1], arr[i, 2]});
    
        2
  •  4
  •   rossipedia    6 年前

    多维数组是一个连续的内存块,因此您必须将它们视为单个数组。试试这个:

    var dict = arr.Cast<string>() 
      .Select((s, i) => new { s, i })
      .GroupBy(s => s.i / arr.GetLength(1))
      .ToDictionary(
        g => g.First().s,
        g => g.Skip(1).Select(i => i.s).ToArray()
      );
    

    解释如下:

    // First, cast it to an IEnumerable<string>
    var dict = arr.Cast<string>() 
    
      // Use the Select overload that lets us get the index of the element,
      // And we capture the element's index (i), along with the element itself (s)
      // and put them together into an anonymous type [1]
      .Select((s, i) => new { s, i })
    
      // .GetLength(dimension) is a method on multidimensional arrays to 
      // get the length of a given dimension (pretty self-explanatory)
      // In this case, we want the second dimension, or how wide each 
      // row is: [x,y] <- we want y
      // Divide the element index (s.i) by that length to get the row index 
      // for that element
      .GroupBy(s => s.i / arr.GetLength(1))
    
      // Now we have an Grouping<int, IEnumerable<anonymous{string,int}>>
      .ToDictionary(
    
        // We don't care about the key, since it's the row index, what we want
        // is the string value (the `s` property) from first element in the row
        g => g.First().s,
    
        // For the value, we want to skip the first element, and extract
        // the string values (the `s` property), and then convert to an array
        g => g.Skip(1).Select(i => i.s).ToArray()
      );
    

    [1]:见 here 有关匿名类型的文档。

        3
  •  2
  •   Enigmativity    6 年前

    这是我能想到的最简单的方法:

    var arr = new int[4, 3]
    {
        { 1, 2, 3 },
        { 3, 5, 7 },
        { 5, 8, 11 },
        { 7, 11, 15 },
    };
    
    var dict = arr.Cast<int>().Buffer(3).ToDictionary(x => x[0], x => x.Skip(1).ToArray());
    

    这给了我:

    dict

    你只需要使用“system.interactive”来获取 Buffer 接线员。

    或者使用此实现:

    public static IEnumerable<T[]> Buffer<T>(this IEnumerable<T> source, int count)
        =>
            source
                .Select((t, i) => new { t, i })
                .GroupBy(x => x.i / count)
                .Select(x => x.Select(y => y.t).ToArray());
    
        4
  •  1
  •   Diwa    6 年前

    我想你的方法是对的,我唯一怀疑的是你的数组是否是静态的?

    arr.Select((value, index) => new { value, index }) .ToDictionary(x => x.index, x => new string[2]{x.value[x.index][1],x.value[x.index][2]}));
    

    注意:我无法执行和检查代码!对不起的。

        5
  •  1
  •   Sivabalakrishnan    6 年前

    我已经用过整数了。请根据您的要求更改。

    public static void Main()
    { 
        int row=0 , col=0;
        int[,] array = new int[,]
        {
         { 1, 2, 3 },
         { 4, 5, 6 }, 
         { 7, 8, 9 },
         { 10, 11, 12 } 
        };
    
        int flag=0;
    
        for (int i = 0; i < array.Rank; i++)
        {
                    if(flag==0)
                    {
            row= array.GetLength(i);
                        flag=1;
                    }
                    else
                    {
    
             col= array.GetLength(i);       
                    }
    
            }
    
        Dictionary<int,int[,]> dictionary = new Dictionary<int, int[,]>();
    
        for(int i=0;i<row;i++)
        {
    
            dictionary.Add(array[i,0],new int[, ]{{array[i,1]},{array[i,2]}});
    
        }
    
        Console.WriteLine(dictionary[4].GetValue(0,0));
    
    }
    
    推荐文章