vue js находит объект в массиве и затем распространяет его в новый массив с дополнительными свойствами

#arrays #vuejs2 #javascript-objects

#массивы #vuejs2 #javascript-объекты

Вопрос:

У меня есть три массива: объекты цвета, объекты размера, объекты артикула. Они извлекаются из базы данных с помощью вызова API и сохраняются в Vue data(). Затем я строю 2D-матрицу размеров и цветов с артикулом, если он существует, используя операторы map и find

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

Мне нужно присвоить результаты новому массиву (this.matrix), однако для пользовательского интерфейса мне также нужно дополнительное поле (выбрано: false), которого нет в объекте sku. Ему не нужно храниться в базе данных, поскольку оно предназначено только для управления состоянием. Для этого, я думаю, мне нужно использовать Object.assign({selected:false}, артикул), но я не могу понять, куда бы я поместил это в приведенном выше коде. Я должен делать это по мере назначения this.matrix, иначе Vue не будет генерировать получатели и установщики

Каждая ссылка на ячейку в 2D-массиве будет иметь 0 или 1 артикул в массиве sku. Каждому артикулу в массиве sku будет соответствовать слот в 2D-массиве.

Куда бы мне поместить Object.assign, или есть способ получше?

Ответ №1:

Я немного упрощу это, поскольку ваш вопрос на самом деле не связан с 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} ...],
//  [ ... ],
//  [ ....] 
//]   
  

т.е. создает цепочку другого отображения для получения sku представления, а затем сопоставляет с результирующим объектом. Затем вы можете присвоить результат вашей 2D-матрице объектов.

Если ваша матрица довольно большая, и вы не хотите заново создавать новый объект для каждой ячейки в матрице, вы можете использовать тот факт, что map предоставляет индекс в качестве второго необязательного параметра функции со стрелкой: sized.map( (s,i) => cols.map( (c,j) => { ... } . Код будет менее читаемым, но вы можете напрямую манипулировать своей матрицей.

Комментарии:

1. Спасибо, Алекс. Это не совсем то, чего я добивался, поскольку массив sku — это массив объектов, и мне нужен новый объект с выбранным свойством и всеми свойствами объекта sku, если он существует, но это хорошее упрощение техники. Вы правы, это не имеет прямого отношения к Vue, ограничение для Vue заключается в том, что свойства должны существовать, когда вы впервые помещаете объект в хранилище данных, иначе получатели и установщики не создаются. После того, как я написал сообщение, я его доработал — разве это не всегда так! и я опубликовал свое собственное решение ниже, но спасибо за ввод

Ответ №2:

Это было мое решение:

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

Теперь создается новый объект с артикулом и выбирается, и если он находит соответствующий объект с артикулом, то распространяет свойства (через Object.assign) на новый объект. свойство sku существует в обоих исходных объектах, но будет выведено только один раз.

Комментарии:

1. Да, это тоже работает. Я бы все равно добавил еще один, .map( colour => this.style.name colour.colour_code size.code).map( nSku => Object.assign(... чтобы избежать вычисления двух строк — для find() и для значения sku . Например, принцип DNR.

Ответ №3:

Начиная с получения OT сейчас, каждый объект в 2D-массиве ДОЛЖЕН иметь свойство ‘sku’, поэтому он должен существовать в целевом массиве, на случай, если исходный массив равен NULL. Код может быть более читаемым, если я вставлю в переменную, а затем вызову переменную дважды, но он выполняет ту же логику.

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