Найти значение в многомерном массиве и вернуть все элементы c#

#c# #.net #arrays

#c# #.net #массивы

Вопрос:

вот проблема, у меня есть массив, определенный следующим образом:

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

Его данные будут примерно такими:

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

массив используется по мере необходимости моим скриптом. но мне нужно иметь возможность фильтровать массив на основе одного из его измерений и возвращать все доступные соответствия.

Например, фильтрация по измерению [1], при которой требуется, чтобы все совпадало с ‘3’, вернет массив, содержащий:

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

Кто-нибудь может помочь мне с этим?

Большое спасибо.

Ответ №1:

Если вы можете изменить свой массив с int[,] на int[][] , то вы можете легко добиться этого с помощью 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;
  

Если изменение вашего массива не является вариантом, вы могли бы написать Filter функцию следующим образом.

 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;
    }
  }      
}
  

Затем вышеуказанное можно было бы вызвать следующим образом

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

Вы могли бы сделать еще один шаг и реализовать свое собственное расширение Linq для Where функции, которое позволило бы вам фильтровать T[,] массивы. Вот наивный пример, который может помочь вам начать.

 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;
      } 
    }
  }    
}
  

При этом вы можете снова использовать Linq, как в первом примере, для фильтрации массива

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