0

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?

3 Answers 3

1

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks Alex. That is not quite what I was after as the sku array is an array of objects and I need a new object with the selected property and all the properties of the sku object if it exists, but it is a good simplification of the technique. You are right, it is not directly related to Vue, the constraint for Vue is that the properties have to exist when you first push the object into the data store, otherwise the getters and setters are not created. After I had made the post, I worked it out - isn't that always the way! and I have posted my own solution below, but thanks for the input
1

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.

1 Comment

Yeah, that works too. I would still add another .map( colour => this.style.name + colour.colour_code + size.code).map( nSku => Object.assign(... to avoid calculating two strings - for find() and for the value of sku. Like, DNR principle.
0

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
                )
             ) 
         )
     )
 )

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.