0

I would like to remove duplicates of lines in a string with Swift 3. I got to do it but unfortunately at the end of the process the lines lost the order. Here is my code:

// string with 7 lines and 2 duplicates (MacBook and Mac mini)
var str = "MacBook\nMacBook Pro\nMacPro\nMacBook\niMac\nMac mini\nMac mini"

var components = str.components(separatedBy: .newlines)
print(components)

// remove duplicates: first by converting to a Set
// and then back to Array (found in iSwift.org)
components = Array(Set(components))
print(components)

let newStr = components.joined(separator: "\n")
print(newStr)

EDIT: When removing duplicates, I prefer to keep the first one not the last one.

Cue
  • 2,952
  • 3
  • 33
  • 54
  • 2
    You can use [the approach shown here](http://stackoverflow.com/a/25739498/2976878) in order to maintain order. – Hamish Mar 16 '17 at 15:19
  • 1
    When removing duplicates, do you wish to keep the first one or the last one? – rmaddy Mar 16 '17 at 15:29
  • 1
    `let newStr = str.components(separatedBy: .newlines).reduce([]){ $0.contains($1) ? $0 : $0 + [$1] }.joined(separator: "\n")` – Leo Dabus Mar 16 '17 at 15:42
  • @maddy, right question, I wish to keep the first one, I will add this info in the question. – Cue Mar 16 '17 at 15:49

3 Answers3

1

Tweaking @LeoDabus' comment…

let str = "MacBook\nMacBook Pro\nMacPro\nMacBook\niMac\nMac mini\nMac mini"
let components = str.components(separatedBy: .newlines)

let depDuped = components.reduce([]) {
    $0.0.contains($0.1) ? $0.0 : $0.0 + [$0.1]
}.joined(separator: "\n")

If duplicates can occur elsewhere in the string (so "A\nB\nA" would be unchanged), then

let depDuped = components.reduce([]) {
    $0.0.last == $0.1 ? $0.0 : $0.0 + [$0.1]
}.joined(separator: "\n")
Ashley Mills
  • 50,474
  • 16
  • 129
  • 160
1

You can use NSOrderedSet.

var str = "MacBook\nMacBook Pro\nMacPro\nMacBook\niMac\nMac mini\nMac mini"

var components = str.components(separatedBy: .newlines)
print(components)

let orderedSet = NSOrderedSet(array: components)
components = orderedSet.array as! [String]
print(components)

let newStr = components.joined(separator: "\n")
print(newStr)
D31
  • 112
  • 1
  • 10
0

Swift 5 Update from @ashley-mills

let str = "MacBook\nMacBook Pro\nMacPro\nMacBook\niMac\nMac mini\nMac mini"
let components = str.components(separatedBy: .newlines)

let depDuped = components.reduce([]) {
    $0.contains($1) ? $0 : $0 + [$1]
}.joined(separator: "\n")
John Smith
  • 573
  • 6
  • 22