3

How can I remove all null elements from an array object[,] in C#. I've already seen the similar question in StackOverflow : Remove blank values in the array using c#

The problem is they are using a method called Where() to solve the problem with a simple array type object[], but I'm dealing with an array type object[,] and there is unfortunately no method Where() implemented for this class. For example :

object[,] data = new object[2,2]{{null,null},{1,2}};

Then, data contains :

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

As you can see (in my specific case), if one element is null then all the row of this element is null. I would like to get :

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

Any help ?

0

2 Answers 2

3

Well there is no LINQ Where for two dimensional arrays. If you can change your array definition to be an object[][] you can use a foreach to iterate through the "rows" and filter out rows that have all nulls.

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();
    }
}
Sign up to request clarification or add additional context in comments.

7 Comments

Hi, thanks for your answer. Did you already test your code ? I'm having an error at the line :var newRow = row.Where(item => item != null).ToArray(); The exception is : System.ArgumentNullException: 'Value cannot be null. Parameter name: source'
This is normal, since the variable row is null at his first occurence.
IList<object[]> cleanRows = Enumerable.Empty<object[]>().ToList();? Is that just var cleanRows = new List<object[]>();?
@BoubacarTraoré Unfortunately I was thinking of an array of arrays rather than a two-d array. I'll delete for now until I can fix it.
@Ry- yes it is, nice catch
|
2

The approach is as follows:

  • Count how many rows you would like to remove
  • Create an array of the appropriate size
  • Copy rows that you would like to keep

Use a helper method to detect rows with a null:

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

Now the implementation would look like this:

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;

3 Comments

Also if “if one element is null then all the row of this element is null” is true then RowHasNull can be data[row, 0] == null. (Is that Enumerable.Range parenthesis in the right spot?)
@Ry- Right, the parenthesis was in a wrong spot. You are also right about data[row,0] but since adding a little generalization "costs" only one line of code, I figured I might as well do it.
Awesome ! Thank you very much, this solved my issue ! You should also correct your second line : var newRowCount = oldRowCount - Enumerable.Range(0, rowCount).Count(r => RowHasNull(data, r)); As you can see the variable rowCount doesn't exist. I guess you mean oldRowCount

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.