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