鳥哥的linux - 在C#中獲取兩個數組之間的“差異”?




鳥哥的linux pdf (4)

以下是LINQ擴展方法的基準。 結果是在開發真實程序期間獲得的。

測試:2個列表(lst1和lst2)每個約250000個對象。 每個對象(類Key)包含一個字符串和一個整數。 第二個列表主要包含與第一個列表相同的條目,但添加了一些新條目,並刪除了一些條目。

我測試了Except擴展方法。

var except = lst2.Except(lst1);

List lst = except.ToList();

這兩行產生了600項“新增”。 我使用StopWatch對象計時。 速度驚人: 220毫秒 。 我使用的計算機絕不是“快速的岡薩雷斯”。 Core 2 Duo T7700 - 2.4GHz。

注意:

這是類Key,它實現了IEquatable i-face。

public class Key : IEquatable<Key>
{
    public int Index { get; private set; }
    public string Name { get; private set; }

    public Key(string keyName, int sdIndex)
    {
        this.Name = keyName;
        this.Index = sdIndex;
    }

 // IEquatable implementation
    public bool Equals(Key other)
    {
        //Check whether the compared object is null.
        if (Object.ReferenceEquals(other, null)) return false;
        //Check whether the compared object references the same data.
        if (Object.ReferenceEquals(this, other)) return true;
        //Check whether the products' properties are equal.
        return Index.Equals(other.Index) && Name.Equals(other.Name);
    }

    // If Equals() returns true for a pair of objects 
    // then GetHashCode() must return the same value for these objects.
    public override int GetHashCode()
    {
        //Get hash code for the name field if it is not null.
        int hashKeyName = Name == null ? 0 : Name.GetHashCode();
        //Get hash code for the index field.
        int hashKeyIndex = Index.GetHashCode();
        //Calculate the hash code for the Key.
        return hashKeyName ^ hashKeyIndex;
    }
}

假設我有這兩個數組:

var array1 = new[] {"A", "B", "C"};
var array2 = new[] {"A", "C", "D"};

我想得到兩者之間的差異。 我知道我可以用幾行代碼編寫這個,但我想確保我沒有錯過內置語言功能或LINQ擴展方法。

理想情況下,我最終會得到以下三個結果:

  • 不在array1中的項目,但在array2(“D”)中
  • 不在array2中的項目,但在array1(“B”)中
  • 兩者中的項目

提前致謝!


來自MSDN 101 LINQ樣本 ....

public void Linq52() {
    int[] numbersA = { 0, 2, 4, 5, 6, 8, 9 };
    int[] numbersB = { 1, 3, 5, 7, 8 };

    IEnumerable<int> aOnlyNumbers = numbersA.Except(numbersB);

    Console.WriteLine("Numbers in first array but not second array:");
    foreach (var n in aOnlyNumbers) {
        Console.WriteLine(n);
    }
}

如果你有LINQ可用,你可以使用ExceptDistinct 。 您在問題中要求的集合分別為:

- array2.Except(array1)
- array1.Except(array2)
- array1.Intersect(array2)

我必須使用非常大的數據集來做類似的事情。 如果你要處理幾千左右,請使用Linq的東西,因為它更清晰。 但是如果你知道你的數組是預先排序的,那麼運行這樣的合併可以顯著加快它的速度,因為它只需要一次通過數據,而不需要分配與Linq版本一樣多的內存。

int iA = 0;
int iB = 0;
List<int> inA = new List<int>();
List<int> inB = new List<int>();
List<int> inBoth = new List<int>();
while (iA < numbersA.Length && iB < numbersB.Length)
{
    if (numbersA[iA] < numbersB[iB])
    {
        inA.Add(numbersA[iA++]);
    }
    else if (numbersA[iA] == numbersB[iB])
    {
        inBoth.Add(numbersA[iA++]);
        ++iB;
    }
    else
    {
        inB.Add(numbersB[iB++]);
    }
}
while (iA < numbersA.Length)
{
    inA.Add(numbersA[iA++]);
}
while (iB < numbersB.Length)
{
    inB.Add(numbersB[iB++]);
}

同樣,只有在處理數十萬個值時才需要這樣做。





arrays