0
class MyClass:UIViewController{
   var myArr = ["John", "Eugene", "George", "John", "Lucy", "George"]
   var myArr2 = ["28 years old", "20 years old", "30 years old", "28 years old", "18 years old", "30 years old"]
   var myArr3 = ["3rd Avenue", "Long Beach rd.", "Hollywood Blvd.", "3rd Avenue", "5th street", "Hollywood Blvd."]

   viewDidLoad(){
      super.viewDidLoad()
      removeRepeatedStringsFromArrays(myArr, [myArr2, myArr3])
   }

   func removeRepeatedStringsFromArrays(keyArray: [String], valuesArrays: [[String]]) -> [[String]]{
   //do the func and I want myArr to be changed directly in func like:
   keyArray = myArr.withoutRepeats
   //and other arrays to be returned with removed repeated indexes from keyArray indexes
   }
}

Expected results after code execution:

myArr = ["John", "Eugene", "George", "Lucy"]
myArr2 = ["28 years old", "20 years old", "30 years old", "18 years old"]
myArr3 = ["3rd Avenue", "Long Beach rd.", "Hollywood Blvd.", "5th street"]

Can the function changes myArr2 and myArr3 inside the function or I have to return them in [[String]] and do this:

myArr2 = removeRepeatedStringsFromArrays(myArr, [myArr2, myArr3]).0
myArr3 = removeRepeatedStringsFromArrays(myArr, [myArr2, myArr3]).1

?

1
  • Just to check – you have an array, and you want to remove duplicates, and also remove the corresponding entries at the same positions from some other arrays as well? Commented Apr 8, 2015 at 23:37

2 Answers 2

1

No, you won’t be able to write a function into which you pass an array of arrays and which removes entries from the source arrays. You are going to have to remove them directly within the method. You can do this by first creating a function that finds the indices of only the first unique entries:

func indicesOfUniques<T: Hashable>(source: [T]) -> [Int] {
    var seen: Set<T> = []
    return filter(indices(source)) {
        if seen.contains(source[$0]) {
            return false
        }
        else {
            seen.insert(source[$0])
            return true
        }
    }
}

Then, with a helper that filters by specific indices:

extension Array {
    func filterByIndex<S: SequenceType where S.Generator.Element == Int>(indices: S) -> [T] {
        return Array(PermutationGenerator(elements: self, indices: indices))
    }
}

you remove all the corresponding indices:

class MyClass {
    var myArr = ["John", "Eugene", "George", "John", "Lucy", "George"]
    var myArr2 = ["28 years old", "20 years old", "30 years old", "28 years old", "18 years old", "30 years old"]
    var myArr3 = ["3rd Avenue", "Long Beach rd.", "Hollywood Blvd.", "3rd Avenue", "5th street", "Hollywood Blvd."]

    func viewDidLoad() {
        removeRepeatedStringsFromArrays()
    }

    func removeRepeatedStringsFromArrays() {

        let uniques = indicesOfUniques(myArr)
        myArr = myArr.filterByIndex(uniques)
        myArr2 = myArr2.filterByIndex(uniques)
        myArr3 = myArr3.filterByIndex(uniques)

    }
}

However, you will probably find it much easier to ditch the arrays altogether and represent this data as a data structure:

struct Person {
  let name: String
  let age: Int
  let address: String
}

class MyClass:UIViewController{
    var people = [
        Person(name: "John", age: 28, address: "3rd Avenue"),
        Person(name: "Eugene", age: 20, address: "Long Beach rd."),
        // etc...
    ]

    viewDidLoad() {
        super.viewDidLoad()
        var seen: Set<String> = []
        people = people.filter {
            if seen.contains($0.people.name) {
                return false
            }
            else {
                seen.insert($0.people.name)
                return true
            }
        }
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

I receive an error on Array extension Use of undeclared type 'Index' and Cannot invoke initializer for type 'PremutationGenerator<C, Indices>' with an argument list of type '(elements: Array<T>, indices: S)' I know that I can use data structure, but my all information is in Arrays and I need exactly this method that You wrote but there is an error in Array extension..
Oops yes, sorry I didn't get a chance to run this directly, and in fact there were a couple of places in my code where the logic was incorrect. Updated know, see if that works for you.
It works now! :) Thank You very much can you tell me from where I can learn Pure Swift ?
0

Arrays in swift use value semantics and are passed by value into methods and functions (they are not passed by reference).So if you modify the array inside the method, this doesnt take any efect outside the scope of that method.To pass the array by reference an be able to modify it, you should pass it using the parameter operator "inout" to make it an in-out parameter. In-out means in fact passing value by reference, not by value. So if you decide to pass the arrays by value, you need to return them as you are currently doing, but if you pass the arrays by reference, you don't need to return anything.

Also to check if an array contains duplicates , you can use this generic method:

func distinct<T: Equatable>(source: [T]) -> [T] 
{
  var unique = [T]()
  for item in source {
    if !contains(unique, item) 
    {
       unique.append(item)
    }
  }
  return unique
}

enter image description here

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.