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

时间:2018-06-29 02:30:07

标签: c# arrays dictionary todictionary

我有一个n-by-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 个答案:

答案 0 :(得分:4)

多维数组是一个连续的内存块,因此您必须像对待单个数组一样对待它们。试试这个:

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]:有关匿名类型的文档,请参见My code

答案 1 :(得分:2)

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

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

您只需要NuGet“ 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());

答案 2 :(得分:1)

我想您的方法是正确的,我唯一的疑问是您的数组是否是静态的?

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

注意:我无法执行并检查代码!抱歉。

答案 3 :(得分:1)

有时不使用linq更容易阅读和更快:

eval()

但是当您确实需要使用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] };

答案 4 :(得分:1)

我已经使用Integer完成了。请根据您的要求进行更改。

ImageView0, ImageView1