1

タイプのリストがいくつかあります:

public List<KeyValuePair<KeyValuePair<string, string>, 
                  List<KeyValuePair<string, string>>>> rawComparisonObject;

リストを構築する KeyValuePair の「キー」に従って、これらのリストの共通部分を取得したい

私は試しました:
List2 = list1.Intersect(list2).Intersect(list3)......etc ですが、ご覧のとおり、必要なものではなく、すべての KeyValuePair 変数と交差しています。

KeyValuePairキーのIntersectリストも試し ましたか?

次の形式で:

    public List<List<KeyValuePair<KeyValuePair<string, string>, List<KeyValuePair<string, string>>>>> getCommon(List<ResourceInformation> input)
    {
        List<List<KeyValuePair<KeyValuePair<string, string>, List<KeyValuePair<string, string>>>>> rawComparisonObject =
            new List<List<KeyValuePair<KeyValuePair<string,string>,List<KeyValuePair<string,string>>>>>();
        foreach (ResourceInformation item in input)
        {
            rawComparisonObject.Add(item.rawComparisonObject);                
        }

        foreach (List<KeyValuePair<KeyValuePair<string, string>, List<KeyValuePair<string, string>>>> item in rawComparisonObject)
        {

        }
        List<List<KeyValuePair<KeyValuePair<string, string>, List<KeyValuePair<string, string>>>>> common =
            new List<List<KeyValuePair<KeyValuePair<string, string>, List<KeyValuePair<string, string>>>>>();
        for (int i = 0; i < (rawComparisonObject.Count-1); i++)
        {
            var keysFromB = new HashSet<KeyValuePair<string, string>>(rawComparisonObject[i].Select(x => x.Key));
            var result = rawComparisonObject[i+1].Where(x => keysFromB.Remove(x.Key));
            common.Add(result.ToList());
        }
        return common;

    }

非常に誤った値を返しました。これを行う簡単な方法はありますか?


オブジェクト間の比較の結果として共通のオブジェクトを取得するために、リンクされたデータ作業でこのデータ構造を使用します

例: バットマン vs. インセプション

返す必要があります:

タイプ : 映画 | 映画

出 演 :クリスチャン・ベール | レオナルド・ディカプリオ

もちろん、すべてが URI リンクで強調表示されます。そのため、URI 用に 1 つ、ラベル用にもう 1 つ keyValuePair が必要です。

この複雑なデータ構造を説明するために最善を尽くしました。それが十分に明確であることを願っています

4

3 に答える 3

3

あなたが書いたコードを理解しているので、これが私の(修正された)翻訳です:

public List<List<KeyValuePair<KeyValuePair<string, string>, List<KeyValuePair<string, string>>>>> getCommon(List<ResourceInformation> input)
{
    var rawComparisonObject = 
        input.Select(item => item.rawComparisonObject).ToList();

    var common = rawComparisonObject.Zip(
        rawComparisonObject.Skip(1), 
        (prevItems, nextItems) => 
            (from next in nextItems
            join prev in prevItems on next.Key equals prev.Key
            select next).ToList()).ToList();

    return common;
}

編集: 上記の翻訳では、中間の空の foreach ループを省略し、結合をフィルターとして使用して、結合基準に合格する「次の」要素のみを投影します。私は、この種のフィルタリングでは結合を好む傾向があります。これは、カバーの下でハッシュを利用してマッチングを効率的に実行することを知っているからです。

私の以前のバージョンの問題は、「グループ結合」変数を使用して結合結果を収集することでした。変更後の内部は、投稿で提供されている元のコード サンプルToList()の変数に類似しています。result外側ToList()は、最終common変数の結果の (再) パッケージ化です。これにより、元のコードと同様の結果が得られると思います。ただし、テストを行って、結果が期待どおりであることを確認することを強くお勧めします。

私見、正しいことは、ジェネリックについてより適切に推論できるようになるまで、ジェネリックの使用を単純化するためにリファクタリングすることです。簡単な暫定的な試みで、次GetCommonのようなジェネリック型に変更しました (後で元に戻します)。

public List<List<KeyValuePair<T, List<T>>>> GetCommon<T>(/*List<ResourceInformation> input*/)

そこから、rawComparisonObjectリストをメソッドのパラメーターにプロモートできます。その過程で、メソッドの現在のパラメーターを置き換えます。入力を使用するvarと、ローカル変数の型を変更することを回避できcommonます (出力の型が期待される戻り値の型と一致するように注意している限り、元の翻訳ではこれが私の失敗でした)。

ここで楽に検討しきれないほど多くのデザインのアイデアや質問があるので、そうしようとせずに締めくくります。これは良い挑戦だったと断言したいと思います。LINQ が適切な選択ではない場合もありますが、適切な選択ではない場合でも、アプローチを変更することで試してみる価値があります。ありがとう!

于 2012-04-18T06:55:23.490 に答える
0

キーで KeyValuePairs のみを交差させたい場合は、カスタムを実装して次のようなメソッドIEqualityComparer<T>を使用する必要があります。Intersect()

class KeyValyePairComparer : IEqualityComparer<KeyValuePair<string, string>>
{
    public bool Equals(KeyValuePair<string, string> x, KeyValuePair<string, string> y)
    {
        return x.Key == y.Key;
    }

    public int GetHashCode(KeyValuePair<string, string> item)
    {
        return item.Key.GetHashCode();
    }
}

上記の実装を使用すると、クエリとの交差を取得できます。

var comparer = new KeyValuePairComparer();
var intersection = list1.Intersect(list2, comparer).Intersect(list3, comparer);
于 2012-04-18T11:49:10.947 に答える
0

linq を使用してこれを行うことができますが、データ モデルをより効率的に変更する必要があります。

var keys = list1.select( kv => kv.Key).intersection(list2.select(kv => kv.Key)
var result = list1.where( key => keys.contains(key).TolLst()
于 2012-04-18T06:45:11.373 に答える