トップページに戻る
次のC#のサンプルへ
前のC#のサンプルへ
11-4 Arrayのuniq
問題
Array(複数の値が配列状になっているもの)xsが与えられたときに、
同じ値が2回以上出現しないように、
2回目以降の出現を取り除いたArrayを返すコードを書いてください。
Rubyで表現すると下のようになります。
irb(main):001:0> xs = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 7, 9]
=> [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 7, 9]
irb(main):002:0> xs.uniq
=> [3, 1, 4, 5, 9, 2, 6, 8, 7]
間違えないように:よくある「ハッシュを使う」「集合オブジェクトを使う」などの方法は
順番が乱れてしまうので使えません。
出現順序を守りつつ、2回目以降の出現だけを取り除いてください。
ソース(LINQで連番付与)
using System;
using System.Linq;
class Program
{
static void Main()
{
int[] intArr = { 3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 7, 9 };
int cnt = 0;
var query = intArr.Select(X => new { rn = ++cnt, Val = X })
.GroupBy(X => X.Val)
.Select(X => new { X.Key, minRn = X.Min(Y => Y.rn) })
.OrderBy(X => X.minRn);
foreach (var each in query) {
Console.WriteLine(each);
}
}
}
ソース(LINQとListジェネリックを使用)
using System;
using System.Linq;
using System.Collections.Generic;
class Program
{
static void Main()
{
int[] intArr = { 3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 7, 9 };
var AppearList = new List<int>();
var query = intArr.Where(X =>
{
if (AppearList.Contains(X)) return false;
else {
AppearList.Add(X);
return true;
}
});
foreach (var each in query) {
Console.WriteLine(each);
}
}
}
実行結果
{ Key = 3, minRn = 1 }
{ Key = 1, minRn = 2 }
{ Key = 4, minRn = 3 }
{ Key = 5, minRn = 5 }
{ Key = 9, minRn = 6 }
{ Key = 2, minRn = 7 }
{ Key = 6, minRn = 8 }
{ Key = 8, minRn = 12 }
{ Key = 7, minRn = 14 }
解説
LINQのみで加工するより、Where拡張メソッドでListジェネリックを使用するのが
分かりやすそうですね。