teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

2

ここは実体化しといた方がいいと思いました

2018/07/17 11:59

投稿

tamoto
tamoto

スコア4346

answer CHANGED
@@ -48,8 +48,9 @@
48
48
  {
49
49
  var result = source
50
50
  .GroupBy(x => x, new OverlapsEqualityComparer<T>())
51
- .Select(x => x.Aggregate((set, set2) => set.Union(set2)));
51
+ .Select(x => x.Aggregate((set, set2) => set.Union(set2)))
52
+ .ToArray();
52
- return (result.Count() == source.Count()) ? result : result.GroupUnion();
53
+ return (result.Length == source.Count()) ? result : result.GroupUnion();
53
54
  }
54
55
  class OverlapsEqualityComparer<T> : IEqualityComparer<IEnumerable<T>>
55
56
  {

1

バグ修正!!!

2018/07/17 11:59

投稿

tamoto
tamoto

スコア4346

answer CHANGED
@@ -1,6 +1,8 @@
1
1
  こんにちは。
2
2
  なんだか面白そうな問題だったので回答してみます。
3
3
 
4
+ (下のコードにはバグがみつかったので、さらに下に追記してます。↓↓↓)
5
+
4
6
  自分はIEqualityComparerを悪用してさっぱり実現してみました。たぶんこれが一番短いと思います(?)
5
7
 
6
8
  ```csharp
@@ -31,4 +33,34 @@
31
33
  5, 7, 9
32
34
  4
33
35
  */
36
+ ```
37
+
38
+ ---
39
+
40
+ 追記
41
+ はわわ……上の実装にはバグがありました……OrderByは一度取ったキーが以後更新されないので「2つ目以降のSetとのみ重複している場合」のマージ処理が行われません……
42
+ 筋肉(再帰)で解決!!!
43
+
44
+ ```csharp
45
+ public static class UnionExtension
46
+ {
47
+ public static IEnumerable<IEnumerable<T>> GroupUnion<T>(this IEnumerable<IEnumerable<T>> source)
48
+ {
49
+ var result = source
50
+ .GroupBy(x => x, new OverlapsEqualityComparer<T>())
51
+ .Select(x => x.Aggregate((set, set2) => set.Union(set2)));
52
+ return (result.Count() == source.Count()) ? result : result.GroupUnion();
53
+ }
54
+ class OverlapsEqualityComparer<T> : IEqualityComparer<IEnumerable<T>>
55
+ {
56
+ public bool Equals(IEnumerable<T> x, IEnumerable<T> y) => x.Intersect(y).Count() != 0;
57
+ public int GetHashCode(IEnumerable<T> obj) => 0;
58
+ }
59
+ }
60
+ ```
61
+
62
+ ```csharp
63
+ // つかう
64
+ var data = new[] { A, B, C, D, E, F };
65
+ var result = data.GroupUnion();
34
66
  ```