If you use your current data structure, you can do this, but the syntax will not be good. Basically, this is similar to what A. Milto suggested in his answer, except that you need a border check to rule out an exception in case of an empty path. Therefore, if you define your paths as follows:
var arrayPaths = new List<int[,]>(); arrayPaths.Add(new[,] { { 0, 0 }, { 0, 1 }, { 1, 1 }, { 2, 1 } }); // Include: starts with (0, 0) arrayPaths.Add(new[,] { { 0, 1 }, { 0, 1 }, { 1, 1 }, { 2, 1 } }); // Include: starts with (0, 1) arrayPaths.Add(new[,] { { 1, 0 }, { 0, 1 }, { 1, 1 }, { 2, 1 } }); // Exclude: starts with (1, 0) arrayPaths.Add(new int[0,0]); // Exclude: has no data
Then the subset of paths starting with (0, 0) or (0, 1) is equal to:
arrayPaths.Where(p => p.GetUpperBound(0) >= 0 && p.GetUpperBound(1) >= 1 && ( (p[0, 0] == 0 && p[0, 1] == 0) || (p[0, 0] == 0 && p[0, 1] == 1) ));
Neville Nazeran had a good suggestion in his comment: using a data structure other than an array of integers to represent a point should lead to a much more understandable code. For example, suppose you define a coordinate like this:
public struct Coordinate { public Coordinate(int x, int y) { X = x; Y = y; } public int X { get; } public int Y { get; } public bool Equals(int x, int y) => X == x && Y == y; }
You can then define the set of paths above as follows:
var objectPaths = new List<List<Coordinate>>(); objectPaths.Add(new List<Coordinate> { new Coordinate(0, 0), new Coordinate(0, 1), new Coordinate(1, 1), new Coordinate(2, 1) }); objectPaths.Add(new List<Coordinate> { new Coordinate(0, 1), new Coordinate(0, 1), new Coordinate(1, 1), new Coordinate(2, 1) }); objectPaths.Add(new List<Coordinate> { new Coordinate(1, 0), new Coordinate(0, 1), new Coordinate(1, 1), new Coordinate(2, 1) }); objectPaths.Add(new List<Coordinate>());
And now a subset of the paths you are interested in:
objectPaths.Where(p => p.Count > 0 && (p[0].Equals(0, 0) || p[0].Equals(0, 1)));
If you need a more concise syntax for specifying paths in your code, you can consider a very simple class to represent the path. For instance:
public class Path : List<Coordinate> { public Path() { } public Path(params (int x, int y)[] coordinates) => AddRange(coordinates.Select(c => new Coordinate(cx, cy))); }
Now you can define a set of paths as:
var paths = new List<Path>(); paths.Add(new Path((0, 0), (0, 1), (1, 1), (2, 1))); paths.Add(new Path((0, 1), (0, 1), (1, 1), (2, 1))); paths.Add(new Path((1, 0), (0, 1), (1, 1), (2, 1))); paths.Add(new Path());
And the syntax for choosing the right subset is the same as before.