簡體   English   中英

從列表中刪除對象

[英]Remove objects from list

我有以下清單 -

public class edgeData
{
    public string source { get; set; }
    public string target { get; set; }
}

var edgeList = new List<edgeData>();
var linkCount = 1;

我想刪除的edgeData從條目edgeList當源共同出現小於或等於linkCount

例如建立我的 edgeData -

var newEdge = new edgeData();
newEdge.source = "James";
newEdge.target = 1;
edgeList.Add(newEdge);

var newEdge = new edgeData();
newEdge.source = "Greg";
newEdge.target = 2;
edgeList.Add(newEdge);

var newEdge = new edgeData();
newEdge.source = "James";
newEdge.target = 3;
edgeList.Add(newEdge);

然后處理刪除出現的小於或等於linkCount -

public List<edgeData> RemoveLinks(List<edgeData>() edgeList, int linkCount)
{
    var updatedEdgeData = new List<edgeData>();

    // logic

    return updatedEdgeData;
}

所以在這個例子中,包含“Greg”作為源的條目將被刪除,因為他只出現了一次,這等於linkCount。

我嘗試使用 for 循環執行此操作,但是這很快變得非常難看,並且相信 Linq 是最佳選擇,但是我該如何實現呢?

您可以執行以下操作

edgeList.GroupBy(x=>x.source)
                   .Where(x=>x.Count()>linkCount)
                   .SelectMany(x=>x)
                   .ToList();

您需要Group由源和篩選出具有項小於組linkCount

另請注意,根據 OP, edgeData.target是一個字符串,但您的代碼將其顯示為數字。 希望這是一個錯字。

更新

正如 Harald 指出的那樣,如果組的規模很大,你也可以使用,

edgeList.GroupBy(x=>x.source)
                   .Where(x=>x.Skip(linkCount).Any())
                   .SelectMany(x=>x)
                   .ToList()

當源總體出現小於或等於 linkCount 時,我想從 edgeList 中刪除一個 edgeData 條目。

我認為您希望在最終結果中只需要輸入序列中具有屬性Source值的項目,該值在您的序列中出現的次數比linkCount

因此,如果linkCount等於 5,則您只想保留在輸入序列中此Source至少出現 5 次的那些記錄。

為此,我們需要將您的輸入分組為具有相同Source值的組。 之后,我們只保留那些包含更多linkCount元素的組:

IEnumerable<EdgeData> result = edgeList.GroupBy( edgeItem => edgeItem.Source)

    // keep only the groups with enough elements:
    .Where(group => group.Skip(linkCount).Any())

    // Ungroup, so we get a neat sequence
    .SelectMany(group => group);

GroupBy 的結果是一個對象序列,其中每個對象都實現IGrouping<string, EdgeData> 這個對象本身就是一個EdgeData序列,其中每個Source屬性都具有相同的值。 該值位於 IGrouping 的Key中。

創建組后,我只保留其中包含超過 linkCount 個項目的組。 我這樣做是通過跳過組所在序列的第一個 LinkCount 項目,如果還有任何項目,那么顯然該組有多個 linkCount 項目。

我不想使用 Count(),因為如果您的組有無數個項目,那么計算所有這些項目會浪費處理能力,如果您可以在看到超過 linkCount 后停止計數.

Where 的結果是IGrouping<string, EdgeData>的序列 要取消分組,我們使用SelectMany ,這使其再次成為EdgeData的整潔序列。

基本上只需計算名稱的出現次數,然后在列表中循環並刪除您不喜歡的名稱(連接不足)

        Dictionary<string, int> occurrence = new Dictionary<string, int>();
        foreach (edgeData edge in edgeList)
        {
            if (occurrence.ContainsKey(edge.source)) 
                occurrence[edge.source] += 1;
            else
                occurrence[edge.source] = 1;
        }

        int counter = 0;
        while(counter < edgeList.Count)
        {
            if (occurrence[edgeList[counter].source] < linkCount)
                edgeList.RemoveAt(counter);
            else 
                counter++;
        }

暫無
暫無

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

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