1

2 つの 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}};

これら 2 つの文字列配列を結合する方法はありますか。

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

注: すべての名前フィールドは一意です。

助けてくれてありがとう!=)

4

3 に答える 3

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; 
    }
}
于 2013-02-20T15:29:42.943 に答える
2

したがって、ここでの本当の問題は、値間のマッピングを格納するために 2 次元配列を使用していることです。それはそのための非常に良いデータ構造ではありません。Dictionaryorは、Lookupそれぞれが値にマップされるキーのコレクションを論理的に表すため、はるかに効果的ですが、キーと値の両方を保持するオブジェクトのリストまたはシーケンスがあれば十分です。

ここで何かを行う前に、2 次元配列の行をシーケンスとして取得するための便利なヘルパー メソッドがあります。後で使用します。

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

これで、2 つの配列をペアのシーケンスに簡単にマッピングできます。

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

これを取得したら、LINQGroupJoin演算子を使用して 2 つのシーケンスを結合できます。

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 次元配列に戻すこともできますが、そうすると使いにくくなります。

于 2013-02-20T15:29:52.860 に答える
-2

試す

stringArrayJoined = stringArray1.Concat(stringArray2);
于 2013-02-20T15:11:07.173 に答える