0

I would like to know if there is a more elegant way to write this:

struct S { var state: [String: Any] public var amounts: [Amount] { var result: [Amount] = [] (self.state["amounts"] as? [Any]?)??.forEach({ a in result.append(Amount(a)) }) return result } } struct Amount { init(_ any: Any?) {} } 

I have tried using map for array, but I can't find a way to do so.

2
  • 1
    The value of amounts is most likely something more specific than [Any] Commented May 17, 2019 at 7:09
  • Since amounts array would be filled based on optional value from state, I'd suggest to declare it as an optional array ([Amount]?). Commented May 17, 2019 at 7:50

5 Answers 5

4

You could also use guard let and early return, which would make it look bit better.

Here is how I did it,

struct S { var state: [String: Any] public var amounts: [Amount] { guard let amounts = state["amounts"] as? [Any] else { return [] } return amounts.map(Amount.init) } } 
Sign up to request clarification or add additional context in comments.

3 Comments

I agree with this. Very swifty approach and easy to understand compared to the other answers.
Do you think that map(Amount.init) would be more readable than .map { Amount($0) }?
That depends on people to people. I would assume that OP would know basic swift syntax. For me map(Amount.init) is certainly readable and shorter than the one with complete closure.
3
struct S { var state: [String: Any] public var amounts: [Amount] { return (self.state["amounts"] as? [Any] ?? []).map({ Amount($0) }) } } struct Amount { init(_ any: Any?) {} } 

2 Comments

I'm getting an error: Cannot convert value of type 'Amount' to closure result type '[Amount]'
@Rob replace return with return (self.state["amounts"] as? [Any] ?? []).map({ Amount($0) })
2

You are using too many unnecessary optionals here. You should always use as? with a non-optional type. And instead of forEach, use map:

public var amounts: [Amount] { if let anyArray = self.state["amounts"] as? [Any] { return anyArray.map(Amount.init) } else { return [] } } 

Comments

1

You can get that working in a single line,

public var amounts: [Amount] { return (self.state["amounts"] as? [Any])?.map({ Amount($0) }) ?? [] } 

Comments

1
init(_ state: [Amount]) { self.init() guard let amounts = state["amounts"] as? [Any] else { return [] } return amounts.map(Amount.init) } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.