I have these 3 arrays
names = ["tomatoes", "bananas", "carrot", "tshirt", "microwave"]
categories = ["food", "food", "food", "clothing", "kitchen"]
prices = ["1.49", "0.79", "1.99", "7.99", "200.99"]
I want to create and array like this for each of them
["food", "tomatoes", "1.49"]
I have lots of data so i am trying to create a function that will do this more efficiently then I will try to combine everything into one big array. Ex: [["food", "tomatoes", "1.49"], ["food", "bananas", "0.79"], ["food", "carrot", "1.99"], ["clothing", "tshirt", "7.99"], ["kitchen", "microwave", "200.99"]]
I tried using map but I'm not that familiar with programming so I cant wrap my head around this
CodePudding user response:
Not a direct answer to your question but what you really need is to structure your data:
struct Product {
let name: String
let category: Category
let price: Double
}
enum Category: String {
case food, clothing, kitchen
}
Then you can simply create a product array:
var products: [Product] = []
CodePudding user response:
You want to zip three sequences, but the standard library only supports two, for now. See this other answer for a great solution that relies on code generation. Here is another solution that does not:
Array([categories, names, prices].zipped)
import Algorithms // for `compacted`
public extension Sequence where Element: Sequence {
/// Like `zip`, but with no limit to how many sequences are zipped.
var zipped: AnySequence<[Element.Element]> {
.init(
sequence(
state: map { $0.makeIterator() }
) { iterators in
let compacted = iterators.indices.map { iterators[$0].next() }.compacted()
guard compacted.count == iterators.count else {
return nil
}
return .init(compacted)
}
)
}
}
CodePudding user response:
The simple way of doing it is to loop over the three arrays in parallel. To prevent index errors you should work to the bounds of the smallest array. You could do it with a for
loop, but IMO it's cleaner to use 'reduce(into:)
let items = min(names.count, categories.count, prices.count)
let all = ( 0 ..< items ).reduce(into: [[String]]()) {
$0.append( [names[$1], categories[$1], prices[$1] ])
}
or, picking up on @Leo Dabus's good advice:
let products = ( 0 ..< items ).reduce(into: [Product]()) {
$0.append( Product(name: names[$1], category: categories[$1], price: prices[$1]) )
}