3

Problem

Suppose I have an array of strings.

Using only functional programming (map, reduce, etc...), I want to create a new array which doesn't have any punctuation.

Assume that there are no embedded punctuation marks (i.e. they will be by themselves).

let test_arr = [ "This", "is", "a", "test", ";", "try", "it", "." ]
let punc = [ "!":true, ".":true, "?":true, ";":true ]
let new_arr = test_arr.remove_if { punc[ $0 ]? != nil }  // how to implement?

Maybe something like this already exists? I had no luck googling in the Apple docs.

kfmfe04
  • 14,936
  • 14
  • 74
  • 140
  • I don't think is supported natively. Perhaps you could subclass NSArray to implement something like this. – 67cherries Dec 17 '14 at 04:04
  • @68cherries `extension` is the probably the way to go, but I'm having trouble wrapping my head around the problem that `map` is n to n and `reduce` is n to 1, but what I need is n to m. I could use a loop obviously, but trying to avoid it... – kfmfe04 Dec 17 '14 at 04:11
  • if you use map it will actually loop also – Leo Dabus Dec 17 '14 at 04:41
  • @LeonardoSavioDabus the end-result is obviously the same, but `map` allows the compiler to potentially do parallelisation optimisations (hence, is more scalable/preferred) – kfmfe04 Dec 17 '14 at 04:45

1 Answers1

3

I think your best bet would be to use filter() coupled with checking the current element against NSCharacterSet's puncuationCharacterSet(). This should do what you want.

let test_arr = [ "This", "is", "a", "test", ";", "try", "it", "." ]

let charSet = NSCharacterSet.punctuationCharacterSet()
let noPuncuation = test_arr.filter { $0.rangeOfCharacterFromSet(charSet, options: .LiteralSearch, range: nil)?.startIndex == nil }

println(noPuncuation) // [This, is, a, test, try, it]

As a note, you can use the code in this answer to get a list of all the characters in a given character set, or define your own character set like this.

let customCharset = NSCharacterSet(charactersInString: "!@#")
Community
  • 1
  • 1
Mick MacCallum
  • 129,200
  • 40
  • 280
  • 281