[英]Joining Two 2D 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}};
注意:所有名称字段都是唯一的。
在此先感谢您的帮助! =)
我首先将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;
}
}
所以你真正的问题是你使用二维数组来存储值之间的映射。 这不是一个非常好的数据结构。 Dictionary
或Lookup
更有效,因为它在逻辑上表示每个映射到一个值的键集合,尽管在您的情况下,拥有一个包含键和值的对象的列表或序列就足够了:
在做任何事之前,这是一个方便的辅助方法,用于将二维数组的行作为序列输出; 我们稍后会用它:
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的序列)。
如果你真的需要,你可以将它转换回二维数组,但如果你这样做会更难使用。
尝试
stringArrayJoined = stringArray1.Concat(stringArray2);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.