使用 LINQ 或 Lambda 从列表中删除实例?

发布于 2024-07-30 03:13:26 字数 1442 浏览 3 评论 0原文

现在,我进入了一个阶段,将所有数据作为缓存(对象)中的列表获取,接下来要做的就是从列表中删除一些实例。

通常,我会像这样删除:

List<T> list;
List<T2> toBeRemovedItems;
// populate two lists
foreach(T2 item in toBeRemovedItems)
{
    list.Remove(delegate(T one) { 
        // build a condition based on item
        // return true or false
    });
}

更具体地说,我实际上构建或填充动态类(不是正式定义的类)的 toBeRemvoedItems 列表。 例如,T类类似于MyClass,删除的代码是:

class MyClass<C> {
    public string Value1 { get; set; }
    public int Value2 { get; set; }
    public C ObjectC { get; set; }
}
....
List<MyClass<C>> list;
// populate list
// populate toBeRemovedItems. Here is an example of hard-coded codes:
var toBeRemovedLItems = new[] {
    new { Value1="a", Value2 = 1},
    new { Value2="x", Value2 = 10},
    ...
};
// toBeRemovedItems may be the result of Select from a collection
foreach(var item in toBeRemovedLItems)
{
    list.Remove(delegate(MyClass one) {
        return one.Value1 = item.Value1 && one.Value2 < item.Value2;
    });
}

我试图从MSDN中搜索IEnumerable接口中的Remove()方法,但找不到那里的 Remove() 方法(IEnumerable 仅用于枚举是有意义的)。 在List类中,有几个重载的Remove(...)方法。 我不确定是否有其他方法可以使用 LINQ 或 Lambda 表达式从列表中删除项目?

顺便说一句,我考虑了一种对列表进行查询的方法,以获取子集或带有Where条件的新IEnumerable列表,类似于从列表中移动项目。 但是,我更喜欢从缓存列表中删除项目,并且在某些情况下,我无法将类中的列表属性重置为新列表(例如私有集)。

Now I come a stage to get all my data as a list in cache(objects) and my next thing I have to do is to remove some instances from the list.

Normally, I would do removing like this:

List<T> list;
List<T2> toBeRemovedItems;
// populate two lists
foreach(T2 item in toBeRemovedItems)
{
    list.Remove(delegate(T one) { 
        // build a condition based on item
        // return true or false
    });
}

To be more specific, I actually build or populate toBeRemvoedItems list of a dynamic class (not a formal defined class). For example, the T class is something like MyClass and codes for removing are:

class MyClass<C> {
    public string Value1 { get; set; }
    public int Value2 { get; set; }
    public C ObjectC { get; set; }
}
....
List<MyClass<C>> list;
// populate list
// populate toBeRemovedItems. Here is an example of hard-coded codes:
var toBeRemovedLItems = new[] {
    new { Value1="a", Value2 = 1},
    new { Value2="x", Value2 = 10},
    ...
};
// toBeRemovedItems may be the result of Select from a collection
foreach(var item in toBeRemovedLItems)
{
    list.Remove(delegate(MyClass one) {
        return one.Value1 = item.Value1 && one.Value2 < item.Value2;
    });
}

I tried to search for Remove() method in IEnumerable interface from MSDN, but I cannot find the method of Remove() there (it makes sense that IEnumerable is used just for enumeration). In List class, there are several overloaded Remove(...) methods. I am not sure if there any alternative ways to remove items from a list by using LINQ or Lambda expressions?

By the way, I thought about a way to do a query against a list to get a subset or a new IEnumerable list with Where conditions, similar as moving items from a list. However, I prefer to remove items from my cached list, and there some cases I just cannot reset list property in a class to a new list (private set for example).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

我也只是我 2024-08-06 03:13:26

对于不是列表的集合(无法公开 RemoveAll),您仍然可以使用一行删除项目。

要替换内联,只需生成要删除的项目列表,然后运行它并执行删除代码。

var dictionary = new Dictionary<string, string>(){{"foo", "0"}, {"boo", "1"}, {"goo", "1"}};
dictionary
    .Where(where_item =>
        ((where_item.Key == "foo") && (where_item.Value == "0"))
        || ((where_item.Key == "boo") && (where_item.Value == "1"))
    )
    .ToList()
    .ForEach(remove_item => {
        dictionary.Remove(remove_item.Key);
    });

要在副本中替换,只需生成一个过滤后的可枚举并返回一个新副本。

var dictionary0 = new Dictionary<string, string>(){{"foo", "0"}, {"boo", "1"}, {"goo", "1"}};
var dictionary1 = dictionary0
    .Where(where_item =>
        ((where_item.Key == "foo") && (where_item.Value == "0"))
        || ((where_item.Key == "boo") && (where_item.Value == "1"))
    )
    .ToDictionary(each_item => each_item.Key, each_item => each_item.Value);

For collections that are not lists (can't expose RemoveAll), you can still remove items with a one-liner.

To replace inline, just generate a list of items to remove, then run through it and execute remove code.

var dictionary = new Dictionary<string, string>(){{"foo", "0"}, {"boo", "1"}, {"goo", "1"}};
dictionary
    .Where(where_item =>
        ((where_item.Key == "foo") && (where_item.Value == "0"))
        || ((where_item.Key == "boo") && (where_item.Value == "1"))
    )
    .ToList()
    .ForEach(remove_item => {
        dictionary.Remove(remove_item.Key);
    });

To replace in copy, just generate a filtered enumerable and return a new copy.

var dictionary0 = new Dictionary<string, string>(){{"foo", "0"}, {"boo", "1"}, {"goo", "1"}};
var dictionary1 = dictionary0
    .Where(where_item =>
        ((where_item.Key == "foo") && (where_item.Value == "0"))
        || ((where_item.Key == "boo") && (where_item.Value == "1"))
    )
    .ToDictionary(each_item => each_item.Key, each_item => each_item.Value);
謸气贵蔟 2024-08-06 03:13:26
foreach(var item in toBeRemovedLItems) {   
   list.RemoveAll(one => one.Value1 == item.Value1 && one.Value2 < item.Value2); 
}

又太晚了。 那好吧。

foreach(var item in toBeRemovedLItems) {   
   list.RemoveAll(one => one.Value1 == item.Value1 && one.Value2 < item.Value2); 
}

Too late again. Oh well.

大海や 2024-08-06 03:13:26

您可以使用方法RemoveAll

MyClass one; //initialize MyClass
list.RemoveAll(item => one.Value1 == item.Value1 && one.Value2 < item.Value2);

You could use the method RemoveAll:

MyClass one; //initialize MyClass
list.RemoveAll(item => one.Value1 == item.Value1 && one.Value2 < item.Value2);
柳若烟 2024-08-06 03:13:26

您可以使用 LINQ 的Where 方法来过滤掉不应该属于列表一部分的值。 结果是删除了元素的 IEnumerable

var res = list.Where(item => !(one.Value1 == item.Value1 && one.Value2 < item.Value2));

这不会更新原始 List 实例,而是创建一个新的 IEnumerable 并删除值。

You can use LINQ's Where method to filter out values that should not be a part of the list. The result is an IEnumerable<T> with the elements removed.

var res = list.Where(item => !(one.Value1 == item.Value1 && one.Value2 < item.Value2));

This will not updated the original List<T> instance but instead will create a new IEnumerable<T> with the values removed.

拥有 2024-08-06 03:13:26

如果我正确地回答了问题,则从两个列表中生成一个唯一的集合。

为此,您可以使用以下

列表list1;
列表列表2;

List list3 = list1.Except(list2)

list3 将包含唯一的项目。

If I get the question correctly, to produce a unique set from two List.

For this, you can use the following

List list1;
List list2;

List list3 = list1.Except(list2)

The list3 will contain unique items.

榕城若虚 2024-08-06 03:13:26

我同意 Jared 过滤掉某些项目的建议,但看起来 Value1 上的 join 会是一种更有效的方法:

var res = from item1 in list
          join item2 in toBeRemovedList
            on item1.Value1 equals item2.Value1
          where item1.Value2 >= item2.Value2
          select item1;

更新: 显然我的阅读理解失败 - 新方法:

var removeDict = toBeRemovedList.ToDictionary(i => i.Value1, i => i.Value2);
list.RemoveAll(item => {
    int itemToRemoveValue2;
    if(removeDict.TryGetValue(item.Value1, out itemToRemoveValue2))
        return item.Value2 < itemToRemoveValue2;
    return false;
});

当然,如果您要删除的列表可以从字典开始,那就更好了。 最终,我们只是想让 Value1 上的匹配更加高效。

I agree with Jared's suggestion of filtering out certain items, but it looks like a join on Value1 would be a more efficient approach:

var res = from item1 in list
          join item2 in toBeRemovedList
            on item1.Value1 equals item2.Value1
          where item1.Value2 >= item2.Value2
          select item1;

Update: Apparently I fail at reading comprehension - new approach:

var removeDict = toBeRemovedList.ToDictionary(i => i.Value1, i => i.Value2);
list.RemoveAll(item => {
    int itemToRemoveValue2;
    if(removeDict.TryGetValue(item.Value1, out itemToRemoveValue2))
        return item.Value2 < itemToRemoveValue2;
    return false;
});

Of course, it would be even better if your list to remove could start as a dictionary. Ultimately, we're just trying to make our match on Value1 more efficient.

So尛奶瓶 2024-08-06 03:13:26

也许你正在尝试做这样的事情?

List<T> firstList;
List<T2> toBeRemovedItems;
List<T> finalList;

foreach(T item in firstList)
{
    toBeRemovedItems = CheckIfWeRemoveThisOne(item.Number, item.Id);
    if (toBeRemovedItems == null && toBeRemovedItems.Count() == 0)
        finalList.Add(item);
}

这就是我如何解决删除 ListList 之间重复项的问题。 我使用 CheckIfWeRemoveThisOne 函数来检查 item.Number 是否属于某个其他项目,并使用 ID 作为定义特征。 如果它找到另一个项目(重复的),而不是尝试将其从原始列表中删除(我正在返回一个 List 并获得一个 List< /code> 首先进入我的函数,所以我对如何做到这一点有疑问,无论如何),我只是构建了一个新列表 - 如果发现没问题,则将结果添加到其中。

Maybe you're trying to do something like this?

List<T> firstList;
List<T2> toBeRemovedItems;
List<T> finalList;

foreach(T item in firstList)
{
    toBeRemovedItems = CheckIfWeRemoveThisOne(item.Number, item.Id);
    if (toBeRemovedItems == null && toBeRemovedItems.Count() == 0)
        finalList.Add(item);
}

This is how I managed to solve an issue with getting rid of duplicates between a List<ViewModel> and a List<Model>. I used the CheckIfWeRemoveThisOne function to check if the item.Number belonged to some other item, using the ID as the defining characteristic. If it found another item (a duplicate), rather than try and remove it from the original list (which I was getting back a List<Model> and was given a List<ViewModel> into my function in the first place, so I had my doubts as to how I could do it, anyway), I just built a new list -- adding the result into it if it was found to be ok.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文