繁体   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