string[] anagrams = { "from ", " salt", " earn ", " last ", " near ", " form " };
이렇게 되어 있는 배열에...글자들이 존재하며, 글자 하나하나 순서 위치만 다르게 되어 있다.
이를 그룹핑하여 찾게끔 하는것도 linq 의 groupby 를 통해 얻을 수 있다.
먼저 이를 찾기 위해 sort()함수를 통해 글자들을 정렬해야 한다.
private class AnagramEqualityComparer : IEqualityComparer
{
public bool Equals(string x, string y)
{
return getCanonicalString(x) == getCanonicalString(y);
}
public int GetHashCode(string obj)
{
return getCanonicalString(obj).GetHashCode();
}
private string getCanonicalString(string word)
{
char[] wordChars = word.ToCharArray();
Array.Sort(wordChars);
return new string(wordChars);
}
}
아래는 AnagramEqualityComparer 클래스를 이용해서 글자들을 char 로 분리하여 이를 sort 정렬하여 글자마다 groupby 를 통해 찾는다. 결과물은 그대로 소문자로 출력된다.
public void DataSetLinq44()
{
//string[] anagrams = { "from ", " salt", " earn ", " last ", " near ", " form " };
var anagrams = testDS.Tables["Anagrams"].AsEnumerable();
var orderGroups = anagrams.GroupBy(w => w.Field("anagram").Trim(), new AnagramEqualityComparer());
foreach (var g in orderGroups)
{
Console.WriteLine("Key: {0}", g.Key);
foreach (var w in g)
{
Console.WriteLine("\t" + w.Field("anagram"));
}
}
}
대문자로 출력하기 위해서는 a => a.Field<string>("anagram").ToUpper(), 을 하나 더 추가해주면 됩니다.
Enumerable 의 static 함수 중에, GroupBy() 메개변수를 살펴보면...
// 형식 매개 변수:
// TSource:
// source 요소의 형식입니다.
//
// TKey:
// keySelector에서 반환하는 키의 형식입니다.
//
// TElement:
// System.Linq.IGrouping 요소의 형식입니다.
var anagrams = testDS.Tables["Anagrams"].AsEnumerable();
var orderGroups = anagrams.GroupBy(
w => w.Field("anagram").Trim(),
a => a.Field("anagram").ToUpper(),
new AnagramEqualityComparer()
);
foreach (var g in orderGroups)
{
Console.WriteLine("Key: {0}", g.Key);
foreach (var w in g)
{
Console.WriteLine("\t" + w);
}
}