ShevO27
ShevO27

Reputation: 906

How to compare each element of array to other elements?

I need to find pairs in array, i wanted to do it with comparing arr[i] with others starting from arr[i+1] so i won't check for same value twice, but i can't get that going. Here's what i've tried

func findPairs(_ ar: [Int]) -> Int {
    var pairs = 0
    for i in 0..<ar.count {
        var k = i + 1
        for k in 0..<ar.count {
            if ar[i] == ar[k] {
                pairs += 1
            }
        }
    }
    return pairs/2
}

Upd to clarify, in the example i have, it was given as in array [1,2,3,1,2,3,4,5,1] we have 3 pairs [1,1] [2,2] [3,3]

Upvotes: 1

Views: 314

Answers (3)

Leo Dabus
Leo Dabus

Reputation: 236360

The functional approach would be to get the total number of occurrences of the elements and sum half of it:

func findPairs(_ ar: [Int]) -> Int {
    ar.reduce(into: [Int:Int]()) { $0[$1, default: 0] += 1 }.values.reduce(0) { $0 + $1/2 }
}

findPairs([1,2,3,1,2,3,4,5,1])  // 3
findPairs([4, 4, 4, 4, 4])      // 2

Or extending collection constraining the elements to hashable:


extension Collection where Element: Hashable {
    var numberOfPairs: Int {
        reduce(into: [Element:Int]()) { $0[$1, default: 0] += 1 }.values.reduce(0) { $0 + $1/2 }
    }
}

[1,2,3,1,2,3,4,5,1].numberOfPairs  // 3
[4, 4, 4, 4, 4].numberOfPairs      // 2

Upvotes: 2

gcharita
gcharita

Reputation: 8327

You probably need to use i + 1 as the starting index in your inner loop, like that:

func findPairs(_ ar: [Int]) -> Int {
    var pairs = 0
    for i in 0..<ar.count {
        let m = i + 1
        for k in m..<ar.count {
            if ar[i] == ar[k] {
                pairs += 1
            }
        }
    }
    return pairs
}

Also, you can use another array to store the indexes of the pairs so that you do not use the same element for another pair:

func findPairs(_ ar: [Int]) -> Int {
    var pairs = 0
    var pairIndexes = [Int]()
    for i in 0..<ar.count where !pairIndexes.contains(i) {
        let m = i + 1
        for k in m..<ar.count where !pairIndexes.contains(k) {
            if ar[i] == ar[k] {
                pairs += 1
                pairIndexes.append(contentsOf: [i, k])
                break
            }
        }
    }
    return pairs
}

Upvotes: 3

Dogan Altinbas
Dogan Altinbas

Reputation: 451

I think you only need to find the number of pairs in the array. So the following can work for you:

func findPairs(_ ar: [Int]) -> Int {
    var pairs = 0
    for i in 0..<ar.count {
        for k in (i+1)..<ar.count {
            if ar[i] == ar[k] {
                pairs += 1
                break
            }
        }
    }
    return pairs
}

Upvotes: 0

Related Questions