C# LINQで左外部自己結合

static void Main(string[] args)
{
    // 連続して同じ値が来る箇所だけを省いて取得する
    // この場合だと1,2,4,3,4,0が取れることを目指す
    int[] array = { 1, 2, 4, 4, 3, 3, 4, 0, 0 };
    var arrayWithIndex = array.Select((value, index) => new { value, index });
 
    var result =
        from orig in arrayWithIndex
        join alias in arrayWithIndex on orig.index equals alias.index - 1 into _
        from alias in _.DefaultIfEmpty()
        where alias == null || orig.value != alias.value
        select orig.value;
}

前回に引き続いてindex生成してゴニョゴニョするネタを考えたい。というわけで、SQL的な自己結合。これで前後の値との比較が可能になるわけですね! 自己結合自体は普通にjoinで同じソースを置くだけ。例では、「連続して同じ値が入っている箇所」を省くため、インデックスを1つずらして結合。ただ、普通に結合すると最後の値が無いので、結合から抜け落ちてしまう。というわけで、内部結合ではなく外部結合にする。外部結合はDefaultIfEmptyを使って、MSDNに記事があるのをそのまんまな方向で。

var list = new List<int>();
list.Add(array[0]);
for (int i = 1; i < array.Length; i++)
{
	if (array[i] != array[i - 1]) list.Add(array[i]);
}

……でも結局、こんな例ならばList使った方が遥かにスッキリなのであった。意味ないねー。とても。少しはまともな例題が考え出せやしないものなのかしらん。

Comment (0)

Name
WebSite(option)
Comment

Trackback(1) | http://neue.cc/2009/03/06_138.html/trackback

NyaRuRuの日記 : (03/12 06:56)

[.NET]前後の値も利用したシーケンス処理…

// 連続して同じ値が来る箇所だけを省いて取得する // この場合だと1,2,4,3,4,0が取れることを目指す int[] array = { 1, 2, 4, 4, 3, 3, 4, 0, 0 }; C# LINQで左外部自己結合 - neue cc シーケンス中で連続し…

Search/Archive

Category

Profile


Yoshifumi Kawai
Microsoft MVP for .NET(C#)

April 2011
|
March 2017

Twitter:@neuecc
GitHub:neuecc
ils@neue.cc