0

二重の foreach ループがあり、2 つではなく 1 つのループにして高速化したいと考えています。

アイデアは、ディクショナリから 1 つの要素を取得し、それをディクショナリ内のすべての要素と比較することです。

foreach (KeyValuePair<Int64, string> kvp in originCounts)
{
    foreach (KeyValuePair<Int64, string> testkvp in originCounts)
    {
    //Run Comparison on testkvp ad kvp
    }
}

これを1つのループにしたいのですが、何か提案はありますか?

4

6 に答える 6

2

Enumerable.Allすべての要素が同じかどうかを確認するために使用できます。

var firstID = originCounts.First().Value.UserID;
bool allEquals = originCounts.Skip(1).All(o => o.Value.UserID == firstID);

これがあなたが実際に望んでいることのようです。

重複した質問で、合理的な識別子として聞こえるクラスのフィールドを選択しました。

public class MyObject 
{
    public string FirstName{ get; set; }
    public string LastName{ get; set; }
    public int UserID { get; set; }
    public string Address { get; set; }
}

編集:あなたのコメントによると、オブジェクトのフィールドのいずれかが別のオブジェクトの同じフィールドと異なるかどうかを判断したいと考えています。

var first = originCounts.First().Value;
bool allEquals = originCounts.Skip(1).All(o =>
                o.Value.FirstName == first.FirstName
             && o.Value.LastName  == first.LastName
             && o.Value.UserID    == first.UserID
             && o.Value.Address   == first.Address);
于 2012-11-15T15:29:06.267 に答える
0

IComparableインターフェイスを実装する同等の文字列KeyValueクラスを作成できます。

public class ComparableString : IComparable
{
    public Int64 Key { get; set; }

    public string Value { get; set; }

    public int CompareTo(object obj)
    {
        if (obj == null) return 1;

        string otherString = obj as ComparableString;

        if (otherString != null)
        {
            // PLACE YOUR COMPARE LOGIC HERE
            return this.Value.CompareTo(otherString.Value);
        }
        else
        {
            throw new ArgumentException("Object is not a Comparable String");
        }
    }
}

その後、リンクリストを作成して.sortメソッドを実行できます

var originCounts= new List<ComparableString>();
// Logic to fill your list
originCounts.Sort();

.Sortメソッドの平均複雑度はO(n(log n))であり、最悪の場合はO(n ^ 2)です。詳細についてはhttp://msdn.microsoft.com/en-us/library/b0zbh7b6.aspxを参照してください。情報。

.Sort()メソッドを呼び出すと、アイテムのインデックスの前の値がアイテムの値以下であり、現在のインデックスよりも大きいインデックスがまたはよりも大きいことがわかります。あなたのアイテムの価値に等しい。

于 2012-11-15T14:11:34.277 に答える
0

私が正しく理解していれば、個別のオブジェクトを取得するには (IComparable を実装していないか、Equals と GetHashcode をオーバーライドしていません):

var noDups = originCounts
                                 //Any Prop. you want to compare
              .GroupBy(o => new { o.FirstName, o.LastName, o.UserID, o.Address })
              .Select(g => g.First())
              .ToList();
于 2012-11-15T15:47:55.043 に答える
0

質問を誤解して単純化しすぎているのかもしれませんが、文字列内の重複する値を見つけようとしているだけなら、辞書の値プロパティを使用して、それらに対して Distinct を実行できます。

辞書の例を使用して:

    Dictionary<Int64, string> originalCounts = new Dictionary<Int64, string>();
    for (Int64 i = 0; i < 10; i++)
    {
        originalCounts.Add(i, i.ToString());
    }
    originalCounts[5] = originalCounts[3];

    foreach (var kvp in originalCounts)
    {
        Console.WriteLine("{0}  {1}", kvp.Key, kvp.Value);
    }

    Console.WriteLine();

    foreach (var value in originalCounts.Values.Distinct())
    {
        Console.WriteLine("{0}", value);
    }
于 2012-11-15T14:28:52.450 に答える
0

これをlinq構文で試して、パフォーマンスを比較できます

例えば

foreach(KeyValuePair<long, string> kvp1 in originCounts.SelectMany(kvp1 => originCounts.Select(testkvp => kvp1), (kvp1, kvp) => kvp1)) {

}

また

foreach(KeyValuePair<long, string> kvp1 in from kvp1 in originCounts
                                                 from kvp in originCounts.Select(testkvp => kvp1)
                                                 select kvp1) {
}
于 2012-11-15T14:05:54.087 に答える
-1

ディクショナリ エントリを同じディクショナリ内の他のエントリと比較する必要があるのはなぜですか? 重複をチェックしていますか?その場合、使用できますoriginCounts.Distinct()

IEqualityComparer編集: メソッドにを指定する必要がありますDistinct。そうしないと、値ではなく、キー (常に a で区別されますDictionary) のみが比較されます。

于 2012-11-15T14:01:51.457 に答える