首页 > 解决方案 > 按嵌套集合中对象中的属性过滤集合

问题描述

我有三个班级:

public class Error
{
    public List<ErrorOccurrenceDetails> Occurrences { get; set; }
}
public class ErrorOccurrenceDetails
{
    public Dictionary<DateTime, ErrorTime> Times { get; set; }
}
public class ErrorTime
{
    public string Version { get; set; }
}

有一个发生在不同的Error多个。每次都可以出现不同的情况。OccurrencesTimesVersion

我有一个Errors 列表。我需要删除没有提供版本的错误,例如如果用户只想查看版本“1.0”中的错误,则需要删除其他版本(例如“1.1”、“1.2”)。但是,如果版本“1.0”和其他版本出现错误,过滤器应该只删除错误的出现,而不是整个错误。

我试着这样做:

private IList<Error> errors;

private void Filter(string filterVersion)
{
    var errorsToRemove = new Dictionary<int, ErrorOccurrenceDetails>();
    foreach (Error error in this.errors) 
    {
        int index = this.errors.IndexOf(error);
        var listOfSearchedItems = error.Occurences.ToList();
        listOfSearchedItems.RemoveAll(x => x.Times.Values.Any(y => y.Version != filterVersion));

        var errorOccurences = error.Occurences.Except(listOfSearchedItems).ToList();
        if (errorsToRemove.ContainsKey(index))
        {
            errorsToRemove[index].AddRange(errorOccurences);
        }
        else
        {
            errorsToRemove.Add(index, errorOccurences);
        }
    }
}

我正在尝试将所有需要删除的错误放入errorsToRemove字典中,其中 key 是错误索引 in this.errors, value 是不在搜索版本上的出现列表。它有点工作,但有时不会删除坏版本并导致一些正确的版本也被删除,所以有一个我没有注意到的漏洞。

此小提琴中的示例错误列表: https ://dotnetfiddle.net/Kxq50i

标签: c#linq

解决方案


根据 Heinzi 的回答,我决定使用更简单的方法。我想我想Collection was modified; enumeration operation may not execute不惜一切代价避免异常并开始做愚蠢的事情。

private IList<Error> errors;

private static void Filter(string filterVersion)
{
    for (int index = 0; index < errors.Count; index++) 
    {
        Error error = errors[index];
        foreach (var occurrence in error.Occurrences)
        {
            var toRemove = occurrence.Times.Keys.Where(key => occurrence.Times[key].Version != filterVersion).ToList();
            foreach (var key in toRemove)
            {
                occurrence.Times.Remove(key);
            }

            if (occurrence.Times.Count == 0)
            {
                 errors[index] = null; // not deleted to prevent index shift, null is hidden in UI
            }
        }
    }
}

解决方案在这个小提琴中更新。


推荐阅读