У меня есть массив объектов с динамическими ключами и значениями (поэтому не все объекты имеют category_id, размер и т. д.), но я упростил его до этого:
let products_row = [
{
id: 1,
category_id: 11,
options: {
'modelName1': {
size: '2 feet',
colour: 'red',
is_new: true
},
'modelName2': {
size: '4 feet',
colour: 'black',
is_new: true
},
}
},
{
id: 2,
category_id: 21,
options: {
'modelName11': {
size: '2 feet',
colour: 'white',
is_new: false
},
'modelName12': {
size: '4 feet',
colour: 'white',
is_new: false
},
}
},
{
id: 3,
category_id: 31,
options: {
'modelName21': {
size: '8 feet',
colour: 'white',
is_new: false
},
'modelName22': {
size: '4 feet',
colour: 'black',
is_new: true
},
}
},
{
id: 4,
category_id: 41,
options: {
'modelName31': {
size: '8 feet',
colour: 'red',
is_new: true
},
'modelName32': {
size: '8 feet',
colour: 'red',
is_new: true
},
}
}
]
структура данных результата должна быть такой:
let resultArray = [
{
id: 1,
category_id: 11,
model: 'modelName1',
size: '2 feet',
colour: 'red',
is_new: true
},
{
id: 1,
category_id: 11,
model: 'modelName2',
size: '4 feet',
colour: 'black',
is_new: true
},
{
id: 2,
category_id: 21,
model: 'modelName11',
size: '2 feet',
colour: 'white',
is_new: false
},
{
id: 2,
category_id: 21,
model: 'modelName12',
size: '4 feet',
colour: 'white',
is_new: false
},
{
id: 3,
category_id: 31,
model: 'modelName21',
size: '8 feet',
colour: 'white',
is_new: false
},
{
id: 3,
category_id: 31,
model: 'modelName22',
size: '4 feet',
colour: 'black',
is_new: true
},
{
id: 4,
category_id: 41,
model: 'modelName31',
size: '8 feet',
colour: 'red',
is_new: true
},
{
id: 4,
category_id: 41,
model: 'modelName32',
size: '8 feet',
colour: 'red',
is_new: true
},
]
Это то, что я пробовал:
let productsData = [];
products_row
.map((product, p) => Object.entries(product.options || {})
.filter((model, i) => {
return productsData.push(
{
model: model[0],
[Object.keys(product).filter(el => delete product.options)[i]]: Object.values(product)[i],
[Object.keys(model[1] || [])[i]]: Object.values(model[1] || [])[i],
}
)
})
)
console.info(productsData)
Но он возвращает не все данные, что ожидается, потому что я не могу понять, как сохранить предыдущие значения ключей:
[
{
model: 'modelName1',
id: 1,
size: '2 feet',
},
{
model: 'modelName2',
category_id: 11,
colour: 'black',
},
{
model: 'modelName11',
id: 2,
size: '2 feet',
},
{
model: 'modelName12',
category_id: 21,
colour: 'white',
},
{
model: 'modelName21',
id: 3,
size: '8 feet',
},
{
model: 'modelName22',
category_id: 31,
colour: 'black',
},
{
model: 'modelName31',
id: 4,
size: '8 feet',
},
{
model: 'modelName32',
category_id: 41,
colour: 'red',
},
]
Я полностью застрял, любая помощь приветствуется. Спасибо.
вы можете использовать flatMap
и map
Что делает flatMap
, так это то, что возвращаемый массив map
выглядит как
[
[{...1},{...2}],
[{...3},{...4}]
]
это сгладит его и даст
[
{...1},{...2},
{...3},{...4}
]
let products_row = [{id: 1,category_id: 11,options: {'modelName1': {size: '2 feet',colour: 'red',is_new: true},'modelName2': {size: '4 feet',colour: 'black',is_new: true},}},{id: 2,category_id: 21,options: {'modelName11': {size: '2 feet',colour: 'white',is_new: false},'modelName12': {size: '4 feet',colour: 'white',is_new: false},}},{id: 3,category_id: 31,options: {'modelName21': {size: '8 feet',colour: 'white',is_new: false},'modelName22': {size: '4 feet',colour: 'black',is_new: true},}},{id: 4,category_id: 41,options: {'modelName31': {size: '8 feet',colour: 'red',is_new: true},'modelName32': {size: '8 feet',colour: 'red',is_new: true},}}]
let x = products_row.flatMap(({options,...rest}) => Object.entries(options).map(([k,v]) => ({...v,...rest,model:k})))
console.info(x)
надеюсь, шаги были ясны
да спасибо. У меня обычно очень простая структура данных, и я никогда раньше не использовал flatMap, поэтому ваше решение не было для меня очевидным. Никогда не переставай учиться, ха-ха
Довольно сложно анализировать ваше решение и рассуждать о вашей идее, поэтому я не могу исправить ваш код.
Что вы хотите сделать, так это извлечь параметры из каждого объекта и присоединить остальную часть объекта, другими словами, вы хотите выполнить итерацию по каждому параметру для каждой строки продукта.
Есть множество способов добиться этого, вы можете использовать flatMap, как предложил @cmgchess. Легче понять что-то вроде этого:
let result = [];
products_row.forEach(({ options, ...rest }) =>
Object.values(options).forEach((b) => result.push({ ...rest, ...b })),
);
чем вы :) Увидев ваше решение, я немного изменил его, включив ключ объекта: products_row.forEach(({ options, ...rest }) => Object.entries(options).forEach((k,b) => result.push({ ...rest, ...b[1], ...k[1], model:k[0] })), );
cmgchess, ваше решение такое простое! Я не думаю, что я мог бы решить это самостоятельно. Я почему-то пытался решить проблему таким трудным путем LOL Спасибо!