简体   繁体   English

从对象的常规列表中删除所有空条目

[英]Remove all null entries from generic list of Object

This one should be easy, but seems to be eluding me. 这应该很容易,但似乎使我难以理解。

Given this variable: (which contains ~30 records) 给定此变量:(包含约30条记录)

var seriesData = new List<List<object>>();

How do I loop through every record, and omit any record that contains a null, anywhere inside? 如何遍历每条记录,并在内部任何位置省略任何包含null的记录?

Typically, each list inside will look like one of the following: 通常,里面的每个列表看起来都将是以下之一:

["02/16/2019", 5, 7, 10]
["02/17/2019", 3, 15, 2]

and sometimes: 有时:

["02/18/2019", 5, {null}, 10]

This is what I have tried, but, it's not working: 这是我尝试过的,但是没有用:

foreach (List<object> row in seriesData)
{
    if (row.Contains(null)) seriesData.Remove(row);
}

The result I'm ending up with is completely empty? 我最后得到的结果是完全空的?

您可以使用RemoveAll接受谓词:

seriesData.RemoveAll(row => row.Any(x => x == null))

If you can use LINQ, this should be easy: 如果可以使用LINQ,这应该很容易:

seriesData = seriesData
    // filter the lists (x) where all items in them (y) are not null
    .Where(x => x.All(y => y != null))
    // and get the result
    .ToList();

Without LinQ, you may do something like this: 没有LinQ,您可能会执行以下操作:

int i = 0;
while (i < seriesData.Count)
{
    if (seriesData[i].Contains(null))
    {
        seriesData.RemoveAt(i);
    } else {
        i++;
    }
}

This may very well be the most performant solution and not require LinQ if you don't use it already. 这可能是性能最高的解决方案,如果您还没有使用LinQ,则不需要LinQ。 If, on the other hand, you already use LinQ, then style may be more important than performance. 另一方面,如果您已经使用过LinQ,那么样式可能比性能更重要。

As an exercise, I write a version that changes the order of entries but has a lower complexity. 作为练习,我编写了一个版本,该版本可以更改条目的顺序,但复杂度较低。 As stated by @Lee, the above code may have an O(n^2) complexity. 如@Lee所述,以上代码可能具有O(n ^ 2)复杂度。 Here is another version, maybe some benchmarking if performance is really important would help: 这是另一个版本,如果性能真的很重要,也许进行一些基准测试会有所帮助:

int i = 0, last;
while (i < seriesData.Count)
{
    if (seriesData[i].Contains(null))
    {
        last = seriesData.Count - 1;
        seriesData[i] = seriesData[last];
        seriesData.RemoveAt(last);
    } else {
        i++;
    }
}

There are many ways to skin a cat. 有很多方法可以给猫皮。 Here is yet another one that doesn't modify your original list: 这是另一种不会修改原始列表的内容:

var nonulls = seriesData.Where(sd => !sd.Any(o => o == null));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM