Reputation: 153
I have an set of array like this [ [1,2], [2, 3], [4,5], [5, 6,], [7, 8], [1,8,9]].if one item intersect with another then union those items.But I get duplicate items like [[1,2], [2,3], [1,8,9],[1,2,3,8,9][4,5],[5,6], [4,5,6],[7,8]], Where those set of items [1,2],[2,3][1,8,9],[4,5],[5,6],[7,8] are duplicate.
I tried to use reduce method but the output I expected still didn't get it.
var newtotalOverlapingSet = Set<[UICollectionViewLayoutAttributes]>()
if totoalOverLapArray.count > 0{
let _ = totoalOverLapArray.reduce(totoalOverLapArray[0]){ firstSet, secondSet in
if firstSet.intersection(secondSet).count > 0{
newtotalOverlapingSet.insert(Array(firstSet.union(secondSet)))
return firstSet.union(secondSet)
}
return secondSet
}}
Here is my expected output [[1,2,3,7,8,9], [4, 5, 6] ] want to achieve.
Upvotes: 3
Views: 281
Reputation: 1180
Just for fun, tried to stick with reduce
:
func mergeIntersections(of arrays: [[Int]]) -> [Set<Int>] {
return arrays.reduce([Set<Int>]()) { result, nextChunk in
let partialResult = result.reduce(into: (mergedChunk: Set(nextChunk), unmergedChunks: [Set<Int>]())) { (result, existingChunk) in
if !result.mergedChunk.intersection(existingChunk).isEmpty {
result.mergedChunk.formUnion(existingChunk)
} else {
result.unmergedChunks.append(existingChunk)
}
}
return partialResult.mergedChunk.isEmpty
? partialResult.unmergedChunks
: partialResult.unmergedChunks + [partialResult.mergedChunk]
}
}
let arraysOfInts = [[1,2], [2,3], [4,5], [5,6], [7,8], [1,8,9]]
mergeIntersections(of: arraysOfInts) // [{6, 4, 5}, {2, 1, 7, 8, 9, 3}]
But the part I'm really curious about is, how is it related to UICollectionViewLayoutAttributes
? :-)
Upvotes: 2
Reputation: 15748
Create an empty array result
with type [[Int]]
. If intersection
of current Set
with any element of result
is not empty, update the Set
with its union. Else append the Set
in result
array.
func group(arr: [[Int]]) -> [[Int]] {
if (arr.reduce(0) { $0 + $1.count }) == Set(arr.reduce([Int](), +)).count {
return arr
}
let result = arr.reduce(into: [[Int]]()) { (result, subArr) in
if let index = result.firstIndex(where: { !Set($0).intersection(subArr).isEmpty }) {
result[index] = Set(result[index]).union(subArr).sorted()
} else {
result.append(Array(subArr))
}
}
return group(arr:result)
}
Call this method with the array
let arr1 = [[1,2], [2, 3], [4,5], [5, 6,], [7, 8], [1,8,9]]
print(group(arr: arr1))
[[1, 2, 3, 7, 8, 9], [4, 5, 6]]
let arr2 = [[1, 2], [2, 3], [4, 5], [5, 6], [7, 8], [1, 8, 9], [10, 9], [9, 6]]
print(group(arr: arr2))
[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]]
Upvotes: 2
Reputation: 2906
Try this code:
func combine(input: [[Int]]) -> [[Int]] {
return input
.reduce([Set<Int>]()) { acc, elem in
let set = Set(elem)
return acc.firstIndex { !$0.isDisjoint(with: set) }
.map { index in
acc.enumerated().compactMap {
if $0.offset == index {
return acc
.filter { !$0.isDisjoint(with: set) }
.reduce(Set()) { $0.union($1) }
.union(set)
}
return $0.element.isDisjoint(with: set) ? $0.element : nil
}
} ?? acc + [set]
}
.map { Array($0).sorted() }
}
Upvotes: 2