3

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.

1
  • Here are some benchmarks for you: shorturl.at/F2345 Commented May 15, 2019 at 20:53

3 Answers 3

2

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() }
}
Sign up to request clarification or add additional context in comments.

Comments

2

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]]

2 Comments

Your algo gives a wrong answer to: [[1, 2], [2, 3], [4, 5], [5, 6], [7, 8], [1, 8, 9], [10, 9], [9, 6]]
@FabioFelici Fixed now :)
2

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? :-)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.