簡體   English   中英

預先收集 C# 的最有效方法

[英]Most efficient way to prepend collection C#

我有一個 C# 對象數組,需要保留以便我試圖過濾掉重復項(不同的 object 引用相同的屬性值)。 問題是重復的 go 是第一個也是最舊的需要留下來。

使用 IEnumerable 的當前算法(半偽代碼重命名所有內容)

        object[] filter(object[] array)
        {
            var set = new HashSet<Guid>();
            var filtered = new List<object>();

            for (int i = array.Length; i-- > 0;)
            {
                var item = array[i];

                if (!set.Contains(item.ID))
                {
                    set.Add(item.ID);
                    filtered = new List<object>(filtered.Prepend(item));
                }
            }

            return filtered.ToArray();
        }

我知道它目前是 O(n) 但我正在尋找一種非常有效的方法來做到這一點。 如果可能的話,只需 arrays 所以我不需要使用.ToArray() 並再次迭代。

我可以過濾一個大小為 array.length 的數組並將其向后放入,即“filtered[array.length-i] = item”,但我不想有空值。

推入堆棧可以被認為是添加到列表的開頭,而從堆棧中彈出可以被認為是從列表的開頭刪除一個項目。

Stack<T>.Push是一個常數時間操作,只要堆棧有足夠的容量,如文檔所述,因此您可以使用堆棧代替:

// using object[] doesn't make sense here as it doesn't have an ID property,
// so I have taken the liberty to create my interface
IHasID[] Filter(IHasID[] array)
{
    var set = new HashSet<Guid>();
    // if not many elements are expected to be filtered, giving the stack a initial capacity might be better
    var filtered = new Stack<IHasID>(/*array.Length*/);

    for (int i = array.Length; i-- > 0;)
    {
        var item = array[i];

        if (set.Add(item.ID))
        {

            filtered.Push(item);
        }
    }

    // ToArray creates an array in the pop order, O(n)
    // https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.stack-1.toarray?view=net-5.0#remarks
    return filtered.ToArray();
}

interface IHasID
{
    Guid ID { get; }
}

只需使用 LINQ ,它將是單個O(n) CPU、 O(n) RAM 直通迭代器,無需任何進一步分配:

var result = input.Reverse().DistinctBy(x=> x.YourKey);

實現示例在這里 - LINQ's Distinct() on a specific property

你也可以像這樣做同樣的事情,因為它所做的只是創建組迭代器:

var result = input.Reverse().GroupBy(x=> x.YourKey).Select(x=> x.First());

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM