How to count 2 different duplicate values in array - Swift

1.5k views Asked by At

I am creating a Quiz and I have an array of bools and I am trying to find a way to count how many "true" & "false" values there are, so I can present the results of the quiz to the user. I would like to store the results in a variable I can call at a later point.

I have looked at the set collection type but can`t seem to wrap my head around it. Do I initalise set to a bool?

answersArray = [true, false, true, false, true, false, true]

trueAnswersCount = set<Bool>()
6

There are 6 answers

0
Martin Huschenbett On

You can easily use the functional programming power of Swift to obtain a very concise solution for your problem:

let trueAnswersCount = answersArray.filter{$0 == true}.count
2
lchamp On

You can simply loop through your array and increment by one each time the value is true.

Here is a quick example :

var answersArray : [Bool]

answersArray = [true, false, true, false, true, false, true]

var nbTrueAnswers : Int = 0

for value in answersArray {
    if (value == true) {
        nbTrueAnswers++;
    }
}

println("nbTrueAnswers : \(nbTrueAnswers)")

Or see it on : http://swiftstub.com/184888077/

Let me know if it helped :)

0
Mick MacCallum On

You can't just use the native Set type since Sets don't hold duplicate values. For example, the following will emit {false, true}.

let answersArray = [true, false, true, false, true, false, true]
let trueAnswersCount = Set<Bool>(answersArray)

If you're willing to use classes from Cocoa Touch, NSCountedSet simplifies this quite a bit.

let answersArray = [true, false, true, false, true, false, true]

let countedSet = NSCountedSet()
countedSet.addObjectsFromArray(answersArray)

countedSet.countForObject(false) // 3
countedSet.countForObject(true) // 4

NSCountedSet is still a Set and only stores unique values, but it also keeps track of how many times each unique element was added to it.

3
ABakerSmith On

You could make a function that takes a SequenceType and a value and returns the number of times the supplied value matches an element in the sequence:

func countMatches<Seq: SequenceType where Seq.Generator.Element: Equatable> 
                 (arr: Seq, v: Seq.Generator.Element) -> Int {

    return arr.reduce(0) {
        if $1 == v { return $0 + 1 }
        return $0
    }
}

let answersArray = [true, false, true, false, true, false, true]
countMatches(answersArray, true)  // 4
countMatches(answersArray, false) // 3

Or, for Swift 2:

extension SequenceType where Generator.Element: Equatable {
    func countMatches(v: Generator.Element) -> Int {
        return reduce(0) { 
            if $1 == v { return $0 + 1 }
            return $0
        }
    }
}

let answersArray = [true, false, true, false, true, false, true]
answersArray.countMatches(true)  // 4
answersArray.countMatches(false) // 3
0
Hendrik Smoels On

Why not just use filter()?

answersArray = [true, false, true, false, true, false, true]

let trueCount  = answersArray.filter { $0 == true }.count
let falseCount = answersArray.filter { $0 == false }.count
0
Yaqoob Al-Shuaibi On
    var wordCounts = [String: Int]()
    var allWords = ["this","is","a","test","this","is", "another", "test"]
    for word in allWords {
       if wordCounts[word] == nil {
          wordCounts[word] = 1
       } else {
          wordCounts[word]! += 1
       }
     }

    print(wordCounts) // prints: ["a": 1, "this": 2, "test": 2, "another": 1, "is": 2]
    print(wordCounts["this"]!) // get the count of word "this": 2
    allWords = Array(wordCounts.keys) // remove duplicates

or even faster:

    var wordCounts: NSCountedSet!
    var allWords = [true, true, false, false, false, false, true, false] as [Any]

    wordCounts = NSCountedSet(array: allWords)
    print(wordCounts.count(for: true)) // print: 3

see details here