0

I Have a string input INDIA. I want to create a hash which contains different characters in the input and their frequency. How to implement it ?

Ashutosh Pandey
  • 238
  • 2
  • 11

1 Answers1

0

NSOrderedSet could be fit for the purpose, but the issue (in this use case) is that it's an unordered collection (just a bag), so to maintain the order of the characters in the input string in the produced hash, some fixes would need to be added that would reduce the useability of the NSOrderedSet approach in the first place.

Another alternative is to implement your own "ordered bag", which counts the frequency of each character in the input string, and produces an array of 2-element tuples (ordered collection), where the first tuple members annotates the character and the second the count of that character in the input string.

extension Collection where Iterator.Element: Hashable {
    var frequencies: [(Iterator.Element, Int)] {
        var seen: [Iterator.Element: Int] = [:]
        var frequencies: [(Iterator.Element, Int)] = []
        for element in self {
            if let idx = seen[element] {
                frequencies[idx].1 += 1
            }
            else {
                seen[element] = frequencies.count
                frequencies.append((element, 1))
            }
        }
        return frequencies
    }
}

With this you can readily compute your custom hash:

extension String {
    // lowercase the String as not to differ between upper
    // and lower case characters when computing the hash
    var customHash: String {
        return lowercased().characters.frequencies
            .reduce("") { $0 + String($1.0) + String($1.1) }
    }
}

let str1 = "INDIA"
let str2 = "United Kingdom of Great Britain and Northern Ireland"

print(str1.customHash) // i2n1d1a1
print(str2.customHash) // u1n7i5t4e4d4 7k1g2o3m1f1r5a4b1h1l1
dfrib
  • 70,367
  • 12
  • 127
  • 192