2017-11-16 8 views
5

これはタイトルを付けるのが非常に難しい質問です。リスト内で、最初の要素が条件に一致する配列と同じ配列をすべて検索します。

C#では、それぞれint[,]の配列がList<int[,]> pathsに格納されており、それぞれがパスを形成するためにコーディネートのセットを保持しています。 例は{ {0,0}, {0,1}, {1,1}, {2,1} }です。

ここでは、条件に一致するすべてのパスの最初のインデックスの1つと同じ最初のインデックスを持つすべてのパスを保持します。

paths.Where(x => x.GetLength(0) % 2 == 1).ToList(); 

は、これが最初のCOORDSいずれか{0,0}であるか、またはいくつかの配列を含むリストを返す言う:

が良い私は何を意味するか示すために、私は、奇数長さであるすべてのパスを取得すると言います例えば{0,1}である。 pathsbe paths.Where(x=> xの最初の座標は{0,0}か{0,1} )です。どうすればこれを達成できますか?

うまくいけば、私が意味することは理解できます。このよう

+2

これらはパスであり、常に2であるため、2つのプロパティを持つ座標クラスがあると考えていますか? –

+0

'x [0] [0] == 0 && x [0] [1] == 1'のような意味ですか? –

+0

@NevilleNazeraneこれは別のオプションがある場合には最適ではないでしょう。私は既にこの 'path'リストをそのままコードの他の部分に使用しています –

答えて

0

var filteredPaths = paths.Where(x => x[0, 0] == 0 && x[0, 1] == 0 || x[0, 0] == 0 && x[0, 1] == 1); 

をそれとも、同じコレクション型で作業を継続することを好む場合:

List<int[,]> filteredPaths = paths.Where(x => x[0, 0] == 0 && x[1, 0] == 0 || x[0, 0] == 0 && x[1, 0] == 1).ToList(); 
0

ここにあなたの多次元の要素を表している以下のリストを想定し、それについて移動するものをです:

List<short[,]> paths = new List<short[,]> 
        { 
         new short[3, 2] { { 0, 0 }, { 4, 5 }, { 6, 7 } }, 
         new short[3, 2] { { 0, 1 }, { 8, 9 }, { 10, 11 } }, 
         new short[3, 2] { { 1, 1 }, { 1, 3 } ,{ 6, 1 } }, 
         new short[3, 2] { { 2, 1 }, { 3, 5 }, { 7, 7 } } 
        }; 

基準を定義します。

short[,] firstCriteria = new short[1, 2] { { 0, 0 } }; 
short[,] secondCriteria = new short[1, 2] { { 0, 1 } }; 

トランケートのみをフィルタリングするための最初の座標に多次元配列に私たちを有効にする必要があり拡張メソッドを定義します。

static class Helper 
{ 
     public static IEnumerable<short> SliceRow(this short[,] array, short row) 
     { 
      for (var i = array.GetLowerBound(1); i <= array.GetUpperBound(1); i++) 
      { 
       yield return array[row, i]; 
      } 
     } 
} 

その後、あなたが行うことができます:あなたは、あなたの現在のデータを使用して設定している場合

{ { 0, 0 }, { 4, 5 }, { 6, 7 } , 
    { 0, 1 }, { 8, 9 }, { 10, 11 } } 
1

var resutSet = 
      paths.Where(e => e.SliceRow(0).SequenceEqual(firstCriteria.Cast<short>()) || 
        e.SliceRow(0).SequenceEqual(secondCriteria.Cast<short>())).ToList(); 

resultSetは今、すなわち与えられた基準を満たす2つの多次元配列を含んでいるでしょう構造体であれば、これを行うことができますが、構文はそれほど美しくはありません。基本的にA. Miltoが答えてくれたようですが、空のパスの場合には例外を投げるのを避けるために境界チェックが必要です。あなたはそのようなあなたのパスを定義するのであれば:

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 

その後で起動パスのサブセット(0、0)、または(0、1)である:

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

ネヴィルNazeraneは良い提案を持っていました彼のコメントでは、整数の配列以外のデータ構造を使って点を表現すると、コードがはるかに理解しやすくなります。

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

次に、あなたはこのように上に与えられたパスの集合を定義することができます:

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>()); 

をそして今、あなたが興味を持っているパスのサブセットであるたとえば、あなたがそうのような座標を定義すると:

objectPaths.Where(p => p.Count > 0 && (p[0].Equals(0, 0) || p[0].Equals(0, 1))); 

コードでパスを指定するためのより簡潔な構文が必要な場合は、パスを表す非常に簡単なクラスと考えることができます。例えば:

public class Path : List<Coordinate> 
{ 
    public Path() { } 

    public Path(params (int x, int y)[] coordinates) => 
     AddRange(coordinates.Select(c => new Coordinate(c.x, c.y))); 
} 

今、あなたはとパスのセットを定義することができます

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()); 

そして、あなたが望んでいたサブセットを選択するための構文は、以前と同じです。

関連する問題