Reputation: 554
I have three arrays: colour objects, size objects, sku objects. These are fetched from the database using an API call and stored in the Vue data(). I then build a 2D matrix of the sizes and colours with the sku if it exists using the map and find operators
this.sizes.map(
size=> this.colours.map(
colour=>(
this.skus.find(
sku=> sku.sku == this.style.name + colour.colour_code + size.code
) || {sku: this.style.name + colour.colour_code + size.code, selected:false}
)
)
)
I need to assign the results to a new array (this.matrix), however for the UI I also need an additional field (selected:false) that is not in the sku object it does not need to live on the database as it is only for state control. To do this I think I need to use Object.assign({selected:false}, sku) but I can't work out where I would put it in the above code. I have to do it as the this.matrix is assigned, otherwise Vue will not generate the getters and setters
Each cell reference in the 2D array will have 0 or 1 skus in the sku array. Every sku in the sku array will have a corresponding slot in the 2D array.
Where would I put the Object.assign, or is there a better way?
Upvotes: 0
Views: 1255
Reputation: 554
Starting to get OT now, Each object in the 2D array MUST have the 'sku' property so it needs to exist in the target array, just in case the source array is NULL. The code may be more readable if I stick in in a variable and then call the variable twice, but it is doing the same logic.
this.sizes.map(
size=> this.colours.map(
colour=>(
skuCode=this.style.name + colour.colour_code + size.code;
Object.assign(
{
sku: skuCode,
selected: false
},
this.skus.find(
sku=> sku.sku == skuCode
)
)
)
)
)
Upvotes: 0
Reputation: 554
This was my solution:
this.sizes.map(
size=> this.colours.map(
colour=>(
Object.assign(
{
sku: this.style.name + colour.colour_code + size.code,
selected: false
},
this.skus.find(
sku=> sku.sku == this.style.name + colour.colour_code + size.code
)
)
)
)
)
This is now creating a new object with sku and selected and if it finds a matching sku object then spreading the properties (via the Object.assign) into a new object. the sku property exists in both source objects but will only be output once.
Upvotes: 1
Reputation: 9706
I will simplify it a little, as your question is not really related to VueJS.
let sizes = [1,2,3];
let cols = ['a','b','c']
let sku = ['1.a', '2.c'];
sizes.map(
s => cols.map(
c => s+"."+c ).map(
x => ({sku: x,
selected: sku.find(s => s === x) ? true : false})))
//result is
//[
// [ {sku: "1.a", selected: true}, {sku: "1.b", selected: false} ...],
// [ ... ],
// [ ....]
//]
i.e. chain another map to arrive at sku
representation and then map to the resulting object. You can then assign the result to your 2D matrix of objects.
If your matrix is quite big and you don't want to re-create a new object for every cell in the matrix, you can use the fact that map provides index as a second optional arrow-function parameter: sized.map( (s,i) => cols.map( (c,j) => { ... }
. The code will be less readable, but you could manipulate your matrix directly.
Upvotes: 1