4

The following class has some variables inside of it.

class Person {
    var age: Int = 4
    var items = [String]()
} 

var allPeople = [Person]()
var allItems = [String]()

Assuming we created initializers for the class and allPeople has n elements in it, I would like to merge all items for each object into a new array

The problem comes when I try to access each index of allPeople, and from there, get the items variable and append it to allItems. But I need to specify a number that changes according to the total number of elements. My initial attempt was to use a for loop. Also using allPeople[allPeople.count - n], something similar to this.

5
  • 3
    What about let allItems = allPeople.flatMap { $0.items }? Commented Dec 4, 2016 at 12:19
  • You're not adding/appending them together. Though good usage of flatmap. I was using map which was incorrect... Commented Dec 4, 2016 at 12:45
  • Please describe what exactly you want to achieve, what you have tried and what the current result (issue) is. Commented Dec 4, 2016 at 13:54
  • FYI I edited my answer Commented Dec 4, 2016 at 15:12
  • What I want to achieve is having an array that has all the objects each person has. After this, I would move on to showing how many repeated objects there are in all the orders, e.g. 2x Radio, 7x Pen, 1x Paper clip, etc. Whenever a new object is added to items, it will update when the user visits the specific ´viewController´ that has the function I was looking for, so it will always be updated. I tried out all the answers and all of them were correct. Commented Dec 4, 2016 at 15:14

3 Answers 3

4

solution1 (this is the swiftiest way):

//if you want to keep adding to the old array
allItems += allPeople.flatMap{$0.items}

//if you want to add into a new array
let newArray = allItems + allPeople.flatMap{$0.items}

// Using 'map' won't work:
allItems = allItems + allPeople.map{$0.items} //error: binary operator '+' cannot be applied to operands of type '[String]' and '[[String]]'

The code above doesn't work because we are adding [String]] to [String] which the + doesn't know how to handle, read:

let john = Person()
john.items = ["a", "b", "c"]

let jane = Person()
jane.items = ["d", "e", "f"]

allPeople.append(john)
allPeople.append(jane)

print(allPeople.map{$0.items}) // [["a", "b", "c"], ["d", "e", "f"]] <-- [[String]] 
// and obviously can't be added to [String]

It is printing Arrays within arrays. So we need to do one more step.

let mapped = allPeople.map{$0.items}

print(Array(mapped.joined())) // ["a", "b", "c", "d", "e", "f"]

so if we want to use map, we should also use joined

solution2 (not very swifty but I just wanted to explain that a flatMap is basically a join + map)

let newJoinedMappedArray = allItems + Array(allPeople.map($0.items).joined())
Sign up to request clarification or add additional context in comments.

1 Comment

Just what I was looking for, if I could up vote you 10 times I would! Thank you for your detailed answer
1

I'm not sure if I understood what your exact problem is but if you just want all of the item arrays of all Person objects in allPeople to be appended to allItems you can simply do:

for person in allPeople {
    allItems.append(contentsOf: person.items)
}

Comments

0

Try this out

for person in allPeople {
    for item in person.items {
        allItems.append(item)
    }
}

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.