7

here is the issue, I have an array defined like below:

int[,] Users = new int[1000,3];

Its data will be something like:

  • 0,1,2
  • 1,2,1
  • 2,3,2
  • 3,3,4
  • 4,2,3 ...

the array is used as needed by my script. but I need to be able to filter the array based on one of its dimensions, and return all available matches.

For example, filtering on dimension [1], wanting all that match '3' will return an array containing:

  • 2,3,2
  • 3,3,4

Could anyone give me a hand with this?

Many thanks.

0

1 Answer 1

14

If you can change your array from int[,] to int[][] then you can easily achieve this using LINQ.

  int[][] users = new int[][]
  {
    new int[]{0,1,2},
    new int[]{1,2,1},
    new int[]{2,3,2},
    new int[]{3,3,4},
    new int[]{4,2,3}
  };


  var result = from u in users 
               where u[1] == 3 
               select u;

If changing your array is not an option then you could write a Filter function as follows.

public static IEnumerable<T[]> Filter<T>(T[,] source, Func<T[], bool> predicate)
{
  for (int i = 0; i < source.GetLength(0); ++i)
  {
    T[] values = new T[source.GetLength(1)];
    for (int j = 0; j < values.Length; ++j)
    {
      values[j] = source[i, j];
    }
    if (predicate(values))
    {
      yield return values;
    }
  }      
}

The above could then be called as follows

var result = Filter(users, u => u[1] == 3);

You could take this a step further and implement your own custom Linq extension for the Where function which would allow you to filter the T[,] arrays. Here is a naive example that could get you started.

public static class LinqExtensions
{
  public static IEnumerable<T[]> Where<T>(this T[,] source, Func<T[], bool> predicate)
  {
    if (source == null) throw new ArgumentNullException("source");
    if (predicate == null) throw new ArgumentNullException("predicate");
    return WhereImpl(source, predicate);
  }

  private static IEnumerable<T[]> WhereImpl<T>(this T[,] source, Func<T[], bool> predicate)
  {      
    for (int i = 0; i < source.GetLength(0); ++i)
    {
      T[] values = new T[source.GetLength(1)];
      for (int j = 0; j < values.Length; ++j)
      {
        values[j] = source[i, j];
      }
      if (predicate(values))
      {
        yield return values;
      } 
    }
  }    
}

With this you can again use Linq as in the first example to filter the array

  var result = from u in users 
               where u[1] == 3 
               select u;
Sign up to request clarification or add additional context in comments.

Comments

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.