加入两个2D字符串数组

时间:2013-02-20 15:08:08

标签: c# string arrays

我有两个2D字符串数组:

string[,] stringArray1 = {
                 {name1, name2, name3, name4, name5}, 
                 {value1, value2, value3, value4, value5}};

string[,] stringArray2 = {
                 {name1, name3, name5, name2, name4}, 
                 {defaultvalue1, defaultvalue3, defaultvalue5, 
                  defaultvalue2, defaultvalue4}};

有没有办法加入这两个字符串数组:

stringArrayJOINED = {
                  {name1, name2, name3, name4, name5}, 
                  {value1, value2, value3, value4, value5}, 
                  {defaultvalue1, defaultvalue2, defaultvalue3, 
                   defaultvalue4, defaultvalue5}};

注意:所有名称字段都是唯一的。

提前感谢您的帮助! =)

3 个答案:

答案 0 :(得分:2)

我首先将MD转换为更有用的东西,

var dic1 =
   Enumerable.Range(stringArray1.GetLowerBound(1), stringArray1.GetUpperBound(1))
   .ToDictionary(
        i => stringArray1[0, i], 
        i => stringArray1[1, i]);

var dic2 =
   Enumerable.Range(stringArray2.GetLowerBound(1), stringArray2.GetUpperBound(1))
   .ToDictionary(
        i => stringArray2[0, i], 
        i => stringArray2[1, i]);

然后,

var trios = dic1.Keys.Select(
                k => new { Key = k, Value = dic1[k], Default = dic2[k] });

然后,如果你真的觉得有必要......

var trioList = trios.ToList();
var stringArrayJOINED = new string[3, trioList.Count];
for (var i = 0; i < trioList.Count; i++)
{
    stringArrayJoined[0, i] = trioList[i].Key;
    stringArrayJoined[1, i] = trioList[i].Value;
    stringArrayJoined[2, i] = trioList[i].Default;
}

如果默认值是稀疏填充的,听起来就像它们一样,就像这样组合,

var robustButDirtyTrios = dic1.Keys.Select(k =>
                new 
                    { 
                        Key = k, 
                        Value = dic1[k], 
                        Default = dic2.FirstOrDefault(p => p.Key == k) 
                    });

然后像这样转换为MDA,

var trioList = robustButDirtyTrios.ToList();
var stringArrayJOINED = new string[3, trioList.Count];
for (var i = 0; i < trioList.Count; i++)
{
    stringArrayJoined[0, i] = trioList[i].Key;
    stringArrayJoined[1, i] = trioList[i].Value;
    var defaultValue = trioList[i].Default;
    if (defaultValue != null)
    {
        stringArrayJoined[2, i] = default; 
    }
}

答案 1 :(得分:2)

所以你真正的问题是你使用二维数组来存储值之间的映射。这不是一个非常好的数据结构。 DictionaryLookup更有效,因为它在逻辑上表示每个映射到值的键集合,尽管在您的情况下具有一个对象的列表或序列就足够了同时拥有一个键和一个值:

在做任何事之前,这是一个方便的辅助方法,用于将二维数组的行作为序列输出;我们稍后会用它:

public static IEnumerable<T> GetRow<T>(this T[,] array, int rowIndex)
{
    for (int i = 0; i < array.GetLength(1); i++)
    {
        yield return array[rowIndex, i];
    }
}

现在我们可以轻松地将两个数组映射成对的序列:

var firstLookup = stringArray1.GetRow(0)
    .Zip(stringArray1.GetRow(1), (a, b) => new { Key = a, Value = b });

var secondLookup = stringArray2.GetRow(0)
    .Zip(stringArray2.GetRow(1), (a, b) => new { Key = a, Value = b });

一旦我们有了这个,我们就可以使用LINQ GroupJoin运算符加入这两个序列:

var finalLookup = firstLookup.GroupJoin(secondLookup, pair => pair.Key
        , pair => pair.Key
        , (pair, matches) => new { pair, matches })
    .ToDictionary(results => results.pair.Key
        , results => new[] { results.pair.Value }.Concat(
            results.matches.Select(group => group.Value)));

(如果您确定没有重复密钥,则可以使用Join而不是GroupJoin,但这很简单并且可以正确处理其他情况。)

最终结果是一个查找,其中有一个键,用于映射到某个值的任一序列中的每个名称;该值是一个字符串序列,表示该键的所有值(在您的情况下,它将始终是一个大小为2的序列)。

如果确实需要,你可以将它转换回二维数组,但是如果你这样做的话会更难使用。

答案 2 :(得分:-1)

stringArrayJoined = stringArray1.Concat(stringArray2);