回答編集履歴

2

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

2018/07/17 11:59

投稿

tamoto
tamoto

スコア4103

test CHANGED
@@ -98,9 +98,11 @@
98
98
 
99
99
  .GroupBy(x => x, new OverlapsEqualityComparer<T>())
100
100
 
101
- .Select(x => x.Aggregate((set, set2) => set.Union(set2)));
101
+ .Select(x => x.Aggregate((set, set2) => set.Union(set2)))
102
102
 
103
+ .ToArray();
104
+
103
- return (result.Count() == source.Count()) ? result : result.GroupUnion();
105
+ return (result.Length == source.Count()) ? result : result.GroupUnion();
104
106
 
105
107
  }
106
108
 

1

バグ修正!!!

2018/07/17 11:59

投稿

tamoto
tamoto

スコア4103

test CHANGED
@@ -1,6 +1,10 @@
1
1
  こんにちは。
2
2
 
3
3
  なんだか面白そうな問題だったので回答してみます。
4
+
5
+
6
+
7
+ (下のコードにはバグがみつかったので、さらに下に追記してます。↓↓↓)
4
8
 
5
9
 
6
10
 
@@ -65,3 +69,63 @@
65
69
  */
66
70
 
67
71
  ```
72
+
73
+
74
+
75
+ ---
76
+
77
+
78
+
79
+ 追記
80
+
81
+ はわわ……上の実装にはバグがありました……OrderByは一度取ったキーが以後更新されないので「2つ目以降のSetとのみ重複している場合」のマージ処理が行われません……
82
+
83
+ 筋肉(再帰)で解決!!!
84
+
85
+
86
+
87
+ ```csharp
88
+
89
+ public static class UnionExtension
90
+
91
+ {
92
+
93
+ public static IEnumerable<IEnumerable<T>> GroupUnion<T>(this IEnumerable<IEnumerable<T>> source)
94
+
95
+ {
96
+
97
+ var result = source
98
+
99
+ .GroupBy(x => x, new OverlapsEqualityComparer<T>())
100
+
101
+ .Select(x => x.Aggregate((set, set2) => set.Union(set2)));
102
+
103
+ return (result.Count() == source.Count()) ? result : result.GroupUnion();
104
+
105
+ }
106
+
107
+ class OverlapsEqualityComparer<T> : IEqualityComparer<IEnumerable<T>>
108
+
109
+ {
110
+
111
+ public bool Equals(IEnumerable<T> x, IEnumerable<T> y) => x.Intersect(y).Count() != 0;
112
+
113
+ public int GetHashCode(IEnumerable<T> obj) => 0;
114
+
115
+ }
116
+
117
+ }
118
+
119
+ ```
120
+
121
+
122
+
123
+ ```csharp
124
+
125
+ // つかう
126
+
127
+ var data = new[] { A, B, C, D, E, F };
128
+
129
+ var result = data.GroupUnion();
130
+
131
+ ```