Skip to main content
1 of 9
Milos
  • 639
  • 5
  • 18

There may be a few Swift idioms and a Foundation api that you could use to wrap this up. Here is a public input function, which is basically the same as your code:

import Foundation

public func input() -> String {
    let handle = NSFileHandle.fileHandleWithStandardInput()
    defer { handle.closeFile() }
    return NSString(data: handle.availableData, encoding: NSUTF8StringEncoding)! // super unlikely to fail
        .stringByTrimmingCharactersInSet(NSCharacterSet.newlineCharacterSet())
}

Now, splitting strings into words and returning them as a sorted dictionary with word counts sounds like useful thing to have around as a String extension. This is simple to implement unless you insist on pure Standard Library solution:

import Foundation

public extension String {
    public var dictionary: [(word: String, count: Int)] {
        var d: [String:Int] = [:]
        enumerateSubstringsInRange(characters.indices, options: .ByWords) { word, _, _, _ in
            guard let word = word?.lowercaseString else { return }
            d[word] = (d[word] ?? 0) + 1
        }
        return d.sort{ $0.0 < $1.0 }.map{ (word: $0, count: $1) }
    }
}

Usage as follows (to produce the same output as your code):

let report = input().dictionary.map{ "\($0) \($1)" }.joinWithSeparator("\n")

print(report)

// The following input ↓
//
// Baa, baa, black sheep,/ Have you any wool?/ Yes, sir, yes, sir,/ Three bags full
//
// ...yields the following output ↓
//
// any 1
// baa 2
// bags 1
// black 1
// full 1
// have 1
// sheep 1
// sir 2
// three 1
// wool 1
// yes 2
// you 1
Milos
  • 639
  • 5
  • 18