2

Say I had two arrays:

var arrayA = ["Yes", "Yes2", "Not Answered", "No"]
var arrayB = ["Yes", "NA", "Yes2", "NA"]

And I wanted to remove the "NA"s from arrayB by doing:

var filtered = arrayB.filter({$0 != "NA"})

How could I remove the items at the same indexes removed in arrayA. I thought about using the find() function, but that only returns the first index a string appears. You can remove overlap from the arrays by:

let res = arrayA.filter { !contains(arrayB, $0) }

but how could I filter an array based on the filtering of another array?

the result would have:

arrayBFiltered = ["Yes", "Yes2"]
arrayAFiltered = ["Yes", "Not Answered"]

Any ideas?

1
  • You have accepted the answer I would consider the least "swift" way and the hackiest way. @Matteo's method is much nicer and much more "swifty". I do wonder why you don't have a data model to hold these data though? If they are so closely related then you should have them in a single model. Commented Jul 7, 2015 at 13:10

3 Answers 3

6

You might prefer using zip:

var arrayA = ["Yes", "Yes2", "Not Answered", "No"]
var arrayB = ["Yes", "NA", "Yes2", "NA"]

let result = filter(zip(arrayA, arrayB)) { (a, b) in b != "NA" }

for (a, b) in result {
    println("A: \(a) -> B: \(b)")
}

EDIT: SWIFT 2.0

In Swift 2.0 it will be even easier to obtain an array of a consolidated ad-hod struct (say ... Foo) for clearer subsequent code:

struct Foo {
    let a: String
    let b: String
}
// Foo.init will be the function automatically generated by the default initialiser

let result = zip(arrayA, arrayB)
    .filter { (a, b) in b != "NA" }
    .map(Foo.init)
// Order of a and b is important

// result is an Array<Foo> suitable for a clearer subsequent code
for item in result {
    print("A: \(item.a) -> B: \(item.b)")
}

Hope this helps

Sign up to request clarification or add additional context in comments.

2 Comments

This is what I was coming back to write. This is the "swift" way of doing this. Although, I question why the OP hasn't created an object to hold these related data?
@Fogmeister As an exercice I added a Swift 2.0 variant ;-)
1

The ideas from How can I sort multiple arrays based on the sorted order of another array could be used here, that would work for two or more arrays:

let arrayA = ["Yes", "Yes2", "Not Answered", "No"]
let arrayB = ["Yes", "NA", "Yes2", "NA"]

// Determine array indices that should be kept:
let indices = map(filter(enumerate(arrayB), { $1 != "NA" } ), { $0.0 } )

// Filter arrays based on the indices:
let arrayAFiltered = Array(PermutationGenerator(elements: arrayA, indices: indices))
let arrayBFiltered = Array(PermutationGenerator(elements: arrayB, indices: indices))

println(arrayAFiltered) // [Yes, Not Answered]
println(arrayBFiltered) // [Yes, Yes2]

Comments

0

Another solution would be to make the remove code directly inside the filter closure:

// both are vars so you can mutate them directly
var arrayA = ["Yes", "Yes2", "Not Answered", "No"]
var arrayB = ["Yes", "NA", "Yes2", "NA"]

arrayA = filter(enumerate(arrayA)){
    arrayB.removeAtIndex($0)
    return $1 != "Na"
}

// use filtered arrayA and arrayB

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.