35

i have objects

var person1 = Person()
person1.name = "Joe"
person1.lastName = "Doe"
person1.age = 21

var person2 = Person()
person2.name = "Julia"
person2.lastName = "Ivanova"
person2.age = 22

var person3 = Person()
person3.name = "Irina"
person3.lastName = "Petrova"
person3.age = 25

var person9 = Person()
person9.name = "Vova"
person9.lastName = "Vovin"
person9.age = 32

var person10 = Person()
person10.name = "Masha"
person10.lastName = "Golovanova"
person10.age = 20

var person11 = Person()
person11.name = "Petra"
person11.lastName = "Andreeva"
person11.age = 27

and multi array

var array = [[person1, person2, person3], [person9, person10, person11]]

how can I iterate through array to get for example a person with name="Masha"

thanks in advance

1

6 Answers 6

67

I would try this:

var array:[[Person]] = [[person1, person2, person3], [person9, person10, person11]]
/*Casting it like this should keep from getting an error later 
   and/or having to recast the objects*/

for people in array {

/*This is going to look at each array in arrays, 
   and call each one 'people' within this loop*/

    for person in people {

    /*Same thing, this is going to look at each item in the people array
       and call each one 'person' within this loop*/

        if person.name == "Masha" {
            return person
        }
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

what if I have "N" times nested array. Then?
21

An interesting way of solving this would be to leverage the flatMap function of Swift.

var array = [[person1, person2, person3], [person9, person10, person11]]

let flatArray = array.flatMap { $0 }

flatArray now is [person1, person2, person3, person9, person10, person11] of type Array<Person>.

Then you can iterate on flatArray to find what you want :

for person in flatArray {
    if person.name == "Masha" {
        // Do something
    }
}

You could even go further by using Swift 2.0 because it allows you to put a where clause in the for :

for person in flatArray where person.name == "Masha" {
    // Do something
}

Comments

19

Here is technique which called 'Chaining'

Playground. Swift 3.1

import UIKit

class Person {
    var name = ""
    var lastName = ""
    var age = 0
}

var person1 = Person()
person1.name = "Joe"
person1.lastName = "Doe"
person1.age = 21

var person2 = Person()
person2.name = "Julia"
person2.lastName = "Ivanova"
person2.age = 22

var person3 = Person()
person3.name = "Irina"
person3.lastName = "Petrova"
person3.age = 25

var person9 = Person()
person9.name = "Vova"
person9.lastName = "Vovin"
person9.age = 32

var person10 = Person()
person10.name = "Masha"
person10.lastName = "Golovanova"
person10.age = 20

var person11 = Person()
person11.name = "Petra"
person11.lastName = "Andreeva"
person11.age = 27

var array = [[person1, person2, person3], [person9, person10, person11]]

array
    .flatMap{$0}
    .forEach { (anyPerson:Person) in

        if anyPerson.name == "Masha" {
            //Do what you need
            print(anyPerson.lastName)
        }
}

Screen-shot from playground: enter image description here

3 Comments

A quick google did not come up with official document on forEach. I did find some blogs mentioned writing an extension to add forEach to Array. Could you point some documents on forEach? Thanks in advance.
@LiweiZ 1. Array conforms to 'SequenceType' protocol. Documentation: link 2. In playground or Xcode -> Hold 'cmd' + hover mouse to the .forEach method and do mouse click.
@ AlexeyBondarchuk Thanks for your reply. Upvoted both your answer and comment.
10

Iterating can be done as in @Rachel's answer. However there are different ways of doing the same thing, and not necessarily by iterating - and in some cases with just one line of code.

If you want to find, then the best way is using the array's filter method - but before that the multi dimensional array should be flattened, using flatMap.

So, to find the first element having a certain name, you can simply do:

let result: Person? = array.flatMap { $0 }.filter { $0.name == "Masha" }.first

3 Comments

Thanks! I have never meet construction { $0 } before. What to ask Google about to find out ?
@AlexeyK Search for Shorthand Argument Names in developer.apple.com/library/ios/documentation/Swift/Conceptual/…
That's a closure syntax simplification - it's a trailing closure using parameters type inference, shorthand argument names and implicit return. Read Closure Expressions
9

Swift 3:

forEach({ element in
  // do what you need
})

1 Comment

That gets vectors of Persons so need another for loop
3

Here is a pretty simple way to do what you need:

let result = array
    .flatMap { $0 }
    .first(where: { $0.name == "Masha" })

First you have to make your array flatted and then you can just get the first element from the array that satisfies the given predicate (in our case, where name is equal to "Masha").

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.