在嵌套列表中搜索

问题描述 投票:0回答:2

我有一个

List<List<Data>>
和一些
List<Data>
,它们填充在 foreach 循环中。因此,在创建新的
List<Data>
之前,我需要检查
List<Data>
中的任何
List<List<Data>>
中是否已存在某些值。如果是这样,我需要返回这个列表,在这个
List<Data>.

中添加数据
    private List<List<DataToShow>> listList;
    private List<DataToShow> list;

    private void sortTestData()
    {
         listList = new List<List<DataToShow>>();

         foreach (DataToShow data in dataPack)
         {
             List<DataToShow> list = new List<DataToShow> { data };

                if (listList.Count != 0)
                    checkModusStatus(data);

                listList.Add(list);
            }
        }

        private void checkModusStatus(DataToShow data)
        {
            for (int i = 0; i < listList.Count; i++)
            {
                var value = listList[i].Where(x => (x.Mode == data.Mode) && (x.State == data.State));
            }        
}

所以我总是得到 null,尽管有相同的条目

除了两个 foreach 循环之外还有什么想法吗?

c# linq list nested
2个回答
2
投票

检查列表列表中的任何列表是否与谓词匹配

是的,您可以检查列表列表中的任何列表是否已包含您正在考虑添加的

DataToShow
的等效实例,如下所示:

bool equivalentInstancePresent = listList.Any(dataList => dataList.Any(data => IsEquivalentInstance(data));

private bool IsEquivalentInstance(DataToShow data)
{
    // your check here
}

使用

Any(predicate)
将迭代相应的
IEnumerable
,并在找到与谓词匹配的元素后立即返回
true
。否则迭代完成后会返回
false

相同 linq 表达式的较短版本:

bool equivalentInstancePresent = listList.Any(dataList => dataList.Any(IsEquivalentInstance);

获取列表列表中与谓词匹配的第一个列表

如果您还需要返回包含等效实例的列表(如问题中所述),您可以使用以下表达式

List<DataToShow> listWithEquivalentInstancePresent = listList.FirstOrDefault(dataList => dataList.Any(IsEquivalentInstance));

按照评论中的要求,您还可以修改谓词以限制每个列表中要检查的女巫项目。注意:我在以下示例中对谓词使用单独的变量。

修改谓词以仅检查前 x 个项目

如果您想将搜索范围限制为每个列表中的前 5 项:

Func<IEnumerable<DataToShow>, bool> firstFiveItemsContainEquivalentInstance = (dataList) => dataList.Take(5).Any(IsEquivalentInstance);
var listWhereFirstFiveItemsContainEquivalentInstance = listOfLists.FirstOrDefault(firstFiveItemsContainEquivalentInstance);

修改谓词以仅检查每个列表中的第 x 个项目

仅检查第一项相对简单,如下所示。

Func<IEnumerable<DataToShow>, bool> firstItemIsEquivalent = (dataList) => IsEquivalentInstance(dataList.FirstOrDefault());
var listWhereFirstItemIsEquivalentInstance = listOfLists.FirstOrDefault(firstItemIsEquivalent);

仅检查每个列表中第二项的谓词如下所示

Func<IEnumerable<DataToShow>, bool> secondItemIsEquivalent = (dataList) => IsEquivalentInstance(dataList.Skip(1).Take(1).SingleOrDefault());

0
投票

对于您的 DataToShow,您需要重写 Equals 方法

public override bool Equals(object obj)
{
    if (obj == null) return false;
    DataToShow x = obj as DataToShow;
    if (x == null) return false;
    else return (x.Mode == this.Mode) && (x.State == this.State);
}

现在您可以使用为集合定义的 Contains 方法

foreach (List<Data> innerlist in listlist) {
    if(innerlist.Contains(data))
        return innerlist;
    return Null;
}

对数据包中的每个数据调用此函数。

© www.soinside.com 2019 - 2024. All rights reserved.