2

I have an array of struct containing several fields. I want to map the array to create another one of struct containing a subset of fields

struct History: {
   let field1: String
   let field2: String
   let field3: String
   let field4: String
}

struct SubHistory: {
   let field1: String
   let field2: String
}

I could use the for in loop. But It may be possible to use a map, no ?

2
  • 1
    can you add an example of the array you trying to map with an expected result ? Commented Feb 21, 2019 at 8:17
  • 1
    let subHistoryArray = historyArray.map{SubHistory(field1: $0.field1, field2: $0.field2)} Commented Feb 21, 2019 at 8:19

3 Answers 3

6

Yes, you can use map in the following way:

let histories: [History] // array of History structs
let subHistories = histories.map { SubHistory(field1: $0.field1, field2: $0.field2) }
Sign up to request clarification or add additional context in comments.

Comments

5

As a slight variation of kiwisip's correct answer: I would suggest to put the logic of “creating a SubHistory from a History” into a custom initializer:

extension SubHistory {
    init(history: History) {
        self.init(field1: history.field1, field2: history.field2)
    }
}

Then the mapping can be simply done as

let histories: [History] = ...
let subHistories = histories.map(SubHistory.init)

Putting the initializer into an extension has the advantage that the default memberwise initializer is still synthesized – attribution for this observation goes to @kiwisip!

1 Comment

And if you create the init(history: History) in an extension to SubHistory, you don't have to implement the default initializer as Swift will generate it for you.
3

Yes, whenever you have an Array , or any type implementing the Collection protocol, where map is defined, you can use map to transform [A] into [B].

kiwisip already gave a good answer, and Martin R suggested a nice variation.

Here's another one.

extension History {

  var subHistory: SubHistory { 
    return SubHistory(field1: field1, field2: field2)
  }
}

// use it like
let histories: [History] = [...]
let subHistories = histories.map { $0.subHistory }

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.