2

I have a big array like that :

var tableau = ["Salut", "Hey", "Salut", "Hey", "Hey", "Mom", "Hey", "Dad", "Mom", "Hey", "Plop"]

And now I want an array with each word sort by the number of repeats so an Array like that :

var tableauTrier = ["Hey", "Salut", "Mom", "Dad", "Plop"]

How can I use the least memory to sort them ? Help me please !

4 Answers 4

6
var tableau = ["Salut", "Hey", "Salut", "Hey", "Hey", "Mom", "Hey", "Dad", "Mom", "Hey", "Plop"]

var counts = [String: Int]()

// generate dictionary of counts for each word
for word in tableau {
    counts[word] = (counts[word] ?? 0) + 1
}

// Sort the tuples based on the count and use map to extract the word
let result = counts.sorted { $0.value > $1.value }.map { $0.key }
print(result)

// ["Hey", "Mom", "Salut", "Plop", "Dad"]
Sign up to request clarification or add additional context in comments.

2 Comments

For better readability since Swift 3 (I think) it can also be written as counts.sorted { $0.value > $1.value }.map { $0.key }
I like that @LeoDabus. It makes the solution more obviously correct. A quick check with the IBM Swift Sandbox verifies that this feature did indeed come with Swift 3.0.
1

Alternatively – just for fun – a solution with NSCountedSet

let tableau = ["Salut", "Hey", "Salut", "Hey", "Hey", "Mom", "Hey", "Dad", "Mom", "Hey", "Plop"]
let set = NSCountedSet(array: tableau)
let array = (set.allObjects as! [String]).sorted(by: {set.count(for: $0) > set.count(for: $1)})
print(array) 
// [Hey, Mom, Salut, Dad, Plop]

5 Comments

What a funny solution
You'll need to make sure Foundation is imported.
@vacawama Yes, but in iOS you will import UIKit anyway which includes Foundation
You're resulting array is [Any]. If you need [String] you'll want to cast result.
True, UIKit includes Foundation, but folks might not import UIKit for a model class.
0

With a little helper array, you can got about it like this:

var tableau = ["Salut", "Hey", "Salut", "Hey", "Hey", "Mom", "Hey", "Dad", "Mom", "Hey", "Plop"]
var unique = Array(Set(tableau))
unique.sort { (str1, str2) -> Bool in
    let str1Count = tableau.reduce(0, { (result, str) -> Int in
        return  str == str1 ? result+1 : result
    })
    let str2Count = tableau.reduce(0, { (result, str) -> Int in
        return  str == str2 ? result+1 : result
    })
    return str1Count > str2Count
}

Comments

0

Here are a solution:

var result = tableau.sorted(by: { current, next in
    tableau.filter { $0 == current }.count > tableau.filter { $0 == next }.count
}).reduce([String](), {
    if $0.contains($1) {
        return $0
    } else {
        var newPartial = $0
        newPartial.append($1)
        return newPartial
    }
})

print(result)  // ["Hey", "Salut", "Mom", "Dad", "Plop"]

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.