从 C# 对象数组中删除 null 元素

3
我该如何在C#中从一个object[,]数组中删除所有null元素?我已经在StackOverflow上看到了类似的问题:使用c#删除数组中的空值
问题在于,他们使用了一个叫做Where()的方法来解决一个简单的数组类型object[]的问题,但我正在处理一个数组类型object[,],而这个类中不幸没有实现Where()方法。例如:
object[,] data = new object[2,2]{{null,null},{1,2}};

然后,data 包含:

[0, 0] [object]:null
[0, 1] [object]:null
[1, 0] [object]:1
[1, 1] [object]:2  

正如您可以看到的(在我的特定情况下),如果一个元素为空,则该元素所在的整行都为空。我希望得到:

[0, 0] [object]:1
[0, 1] [object]:2

需要帮助吗?

2个回答

3

很遗憾,对于二维数组,没有像LINQ Where 这样的方法。如果您可以将数组定义更改为 object[][],则可以使用 foreach 迭代“行”,并过滤掉所有为空的行。

public class RemoveNulls
{
    [Test]
    public void RemoveNullItems()
    {
        var items = new object[][] { new object[] { null, null }, new object[] { 1, 2 } };
        var cleanRows = new List<object[]>();
        foreach (object[] row in items)
        {
            var newRow = row.Where(item => item != null).ToArray();
            if (newRow.Any()) cleanRows.Add(newRow);
        }
        var result = cleanRows.ToArray();
    }
}

嗨,感谢您的回答。您已经测试过您的代码了吗?我在以下这行代码中遇到了错误:var newRow = row.Where(item => item != null).ToArray();异常信息如下:System.ArgumentNullException:“值不能为 null。 参数名: source” - Boubacar Traoré
这是正常的,因为变量 row 在第一次出现时是空的。 - Boubacar Traoré
@BoubacarTraoré 很遗憾,我在考虑一个数组的数组而不是二维数组。在我修复它之前,我将删除它。 - JSteward
@Ry- 是的,很好的发现。 - JSteward
谢谢您的编辑,但我更喜欢@dasblinkenlight的解决方案,因为将我的数组类型更改为object [] []可能会影响整个项目。无论如何,还是感谢您!! - Boubacar Traoré
显示剩余2条评论

2

方法如下:

  • 计算您想要删除的行数
  • 创建一个适当大小的数组
  • 复制您想要保留的行

使用帮助方法来检测具有null的行:

static bool RowHasNull(object[,] data, int row) {
    return Enumerable.Range(0, data.GetLength(1)).Any(c => data[row,c] == null);
}

现在的实现看起来会像这样:

var oldRowCount = data.GetLength(0);
var newRowCount = oldRowCount - Enumerable.Range(0, oldRowCount).Count(r => RowHasNull(data, r));
if (newRowCount == 0) ... // the array is empty, do something about it - e.g. throw an exception
var res = new object[newRowCount, data.GetLength(1)];
int r = 0;
for (var row = 0 ; row != oldRowCount ; row++) {
    if (RowHasNull(data, row)) {
        continue;
    }
    for (int c = 0 ; c != data.GetLength(1) ; c++) {
        res[r,c] = data[row, c];
    }
    r++;
}
return res;

如果“如果一个元素为空,则该元素所在的整行都为空”是正确的,那么RowHasNull可以是data[row, 0] == null。(Enumerable.Range的括号位置正确吗?) - Ry-
@Ry- 对的,括号位置错了。你也是对的,关于 data[row,0] 但是由于添加一点泛化“成本”只需要一行代码,所以我想干脆就这么做吧。 - Sergey Kalinichenko
太棒了!非常感谢,这解决了我的问题!你还应该更正第二行:var newRowCount = oldRowCount - Enumerable.Range(0, rowCount).Count(r => RowHasNull(data, r));正如你所看到的,变量“rowCount”不存在。我想你是指“oldRowCount”。 - Boubacar Traoré

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接