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 ?
Asked
Active
Viewed 689 times
0
-
1How about using an `NSCountedSet` ? – Paulw11 Dec 20 '16 at 08:06
-
Can you guide me how use them with some code. – Ashutosh Pandey Dec 20 '16 at 08:47
-
@AshutoshPandey consider giving feedback on the answer below: did this solve your issue? – dfrib Jan 15 '17 at 12:14
1 Answers
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