-1

How to sort an integer array based on a duplicate values count. here less number of duplicates should come first.

input  [5, 2, 1, 2, 4, 4, 1, 1, 2, 3, 3, 6]
OutPut [5, 6, 4, 4, 3, 3, 2, 2, 2, 1, 1, 1]

Ekambaram E
  • 1,184
  • 1
  • 11
  • 9
  • 1
    Do you need to keep 5 before 6 because in the initial array it was at index 0? Or is it because its value is less, or could it be after the 6? – Larme Mar 10 '22 at 21:58
  • Could be solved with this: `let output = Dictionary(grouping: input) { $0 }.sorted { $0.value.count == $1.value.count ? input.firstIndex(of: $0.key)! < input.firstIndex(of: $1.key)! : $0.value.count < $1.value.count }.flatMap { $0.value }` – Larme Mar 12 '22 at 11:41

2 Answers2

1

Using Martin's comment, here is another approach which aims to reduce the number of loops and conditions we write ourselves by using some functions provided by swift.

// Input
let numbers = [1, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 6]

// Count the occurrences based on Martin's comment
let countDict = numbers.reduce(into: [:], { $0[$1, default: 0] += 1 } )

// Get a sorted array of the countDict keys, sorted by value which
// is the number of occurrences
let sortedKeys
    = countDict.keys
    .sorted { countDict[$0, default: 0] < countDict[$1, default: 0] }

// Initialize an empty array to hold the final sorted numbers
var sortedNumbers: [Int] = []

// Add the elements into the sortedNumbers with in their desired order
for key in sortedKeys {
    sortedNumbers.append(contentsOf: repeatElement(key,
                                                   count: countDict[key, default: 0]))
}

// prints [5, 6, 4, 4, 3, 3, 1, 1, 1, 2, 2, 2] based on the above input
print(sortedNumbers)
Shawn Frank
  • 4,381
  • 2
  • 19
  • 29
-1
let numbers = [5,2,1,2,4,4,1,1,2,3,3,6]
let sortedNumber = numbers.sorted()
print("Input: ",sortedNumber)

var dict = [Int: Int]()
for item in sortedNumber {
    let isExist = dict.contains(where: {$0.key == item})
    if !isExist {
        dict[item] = 1
    } else {
        if let value = dict[item] {
            dict[item] = value + 1
        }
    }
}

var finalArray = [Int]()
let sortedArray = dict.sorted { (first, second) -> Bool in
    return first.value < second.value
}

for d in sortedArray {
    for _ in 1...d.value {
        finalArray.append(d.key)
    }
}
print("Output: ",finalArray)

Input:  [1, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 6]
Output:  [5, 6, 4, 4, 3, 3, 2, 2, 2, 1, 1, 1]
Ekambaram E
  • 1,184
  • 1
  • 11
  • 9
  • There is some room for improvement. As an example the dictionary (histogram) can be simply generated with `let dict = sortedNumber.reduce(into: [:], { $0[$1, default: 0] += 1 })`, compare https://stackoverflow.com/a/30545629/1187415. – Martin R Mar 10 '22 at 20:36