C# LINQで左外部自己結合
- 2009-03-06
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使った方が遥かにスッキリなのであった。意味ないねー。とても。少しはまともな例題が考え出せやしないものなのかしらん。