У меня есть массив объектов, каждый объект имеет один вложенный объект, который мне нужно изменить.
Пример: то, что у меня есть ниже
const array = [{
asset: {key: '1235', type: 'mocFirst'},
id: 27,
marketValuey: 6509,
marketValueySecond: 65033,
marketValueyThird: 650900,
}]
Я хочу получить это:
const array = [{
type: 'mocFirst'
key: '1235',
id: 27,
marketValuey: 6509,
marketValueySecond: 65033,
marketValueyThird: 650900,
}]
Есть мое решение
const array = [{
asset: {key: '1235', type: 'mocFirst'},
id: 27,
marketValuey: 6509,
marketValueySecond: 65033,
marketValueyThird: 650900,
},
{
asset: {key: '12', type: 'mocFirst44'},
id: 27,
marketValuey: 6409,
marketValueySecond: 64033,
marketValueyThird: 640900,
},
{
asset: {key: '1299', type: 'mocFirst'},
id: 271,
marketValuey: 6109,
marketValueySecond: 61033,
marketValueyThird: 610900,
},
{
asset: {key: '1296', type: 'mocFirst'},
id: 272,
marketValuey: 65092,
marketValueySecond: 650332,
marketValueyThird: 6509020,
},
]
const resultArr = array.map(item => {
const { asset, ...newObj} = item;
const { key, type } = item.asset;
return { key, type, ...newObj};
});
Что-нибудь о моем решении? Может быть, это можно сделать лучше? В производстве у меня будет большой массив
Это не совсем подходящий сайт для обзора рабочего кода, если только у вас нет конкретной проблемы, которую нужно решить/цель для достижения (в этом случае, пожалуйста, включите ее в вопрос)
Я не рекомендую то, что было предложено об использовании { key:key }. Язык имеет более краткий синтаксис для этого, и это просто { key }, так что продолжайте использовать его, как вы.
У меня проблемы с производительностью. Ниже я получил ответ, спасибо



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вот, пожалуйста, это рекурсивное решение для выравнивания объекта.
function flat(source, target) {
Object.keys(source).forEach(function(k) {
if (source[k] !== null && typeof source[k] === 'object') {
flat(source[k], target);
return;
}
target[k] = source[k];
});
}
const array = [{
asset: {
key: '1235',
type: 'mocFirst'
},
id: 27,
marketValuey: 6509,
marketValueySecond: 65033,
marketValueyThird: 650900,
},
{
asset: {
key: '12',
type: 'mocFirst44'
},
id: 27,
marketValuey: 6409,
marketValueySecond: 64033,
marketValueyThird: 640900,
},
{
asset: {
key: '1299',
type: 'mocFirst'
},
id: 271,
marketValuey: 6109,
marketValueySecond: 61033,
marketValueyThird: 610900,
},
{
asset: {
key: '1296',
type: 'mocFirst'
},
id: 272,
marketValuey: 65092,
marketValueySecond: 650332,
marketValueyThird: 6509020,
},
]
let flatArr = array.map(item => {
let flatObj = {};
flat(item, flatObj);
return flatObj
});
console.info(flatArr);Просто сгладьте его так:
var outArr = array.map(item => {
// Create the new items
item.key = item.asset.key
item.type = item.asset.item
// Delete the old parent
delete item.asset
return item
})
Единственное ускорение, которое вы можете «потенциально» ввести, — это использование метода for loop вместо метода map. К сожалению, это зависит от того, как компилятор оптимизирует ваш код, и эффект станет заметным, только если вы работаете с очень большими массивами.
На бенчмаркинг можно ссылаться здесь.
Заключительная часть вашего кода должна выглядеть так:
const resultArr = [];
for (let i = 0; i < array.length; i += 1) {
const { asset, ...newObj} = array[i];
const { key, type } = asset;
resultArr.push({ key, type, ...newObj});
}
Важно понимать, что ускорение этого кода будет не очень заметным, и разработчики обычно предпочитают более очевидный/поддерживаемый синтаксис, поэтому ваш первоначальный ответ можно считать правильным. Следовательно, используйте это по своему усмотрению.
Если вам просто нужно преобразовать asset.key и asset.type соответственно в key и type, и вы хотите повысить производительность, ручное назначение полей примерно в 4-5 раз быстрее, чем ваше решение.
например Я создал array с 1000 элементами, чтобы сравнить ваше решение (на создание array1 уходит около 2,5 мс) с моим (около 0,5 мс на создание array2).
const N = 1000;
let array = [];
for (let i = 0; i < N; i++) {
let random_item = {
asset: {
key: Math.random(N),
type: 'mocFirst'
},
id: Math.random(N),
marketValuey: Math.random(N),
marketValueySecond: Math.random(N),
marketValueyThird: Math.random(N)
};
array.push(random_item);
}
const t0 = performance.now();
const array1 = array.map(item => {
const {
asset,
...newObj
} = item;
const {
key,
type
} = item.asset;
return {
key,
type,
...newObj
};
});
console.info(array1[10]);
const t1 = performance.now();
console.info(`Operation took ${t1 - t0} milliseconds.`);
let array2 = [];
for (let i = 0; i < array.length; i++) {
array2.push({
key: array[i].asset.key,
type: array[i].asset.type,
id: array[i].id,
marketValuey: array[i].marketValuey,
marketValueySecond: array[i].marketValueySecond,
marketValueyThird: array[i].marketValueyThird,
});
}
console.info(array2[10]);
const t2 = performance.now();
console.info(`Operation took ${t2 - t1} milliseconds.`);Мне нравится это решение, который я нашел, выполнив поиск «сгладить вложенный объект в javascript».
Вот код в действии из моего любимого ответа:
const crushObj = (obj = {}) => Object.keys(obj || {}).reduce((acc, cur) => {
if (typeof obj[cur] === 'object') {
acc = { ...acc, ...crushObj(obj[cur])}
} else { acc[cur] = obj[cur] }
return acc
}, {})
const obj = {
a:2,
b: {
c:3
}
}
const output = crushObj(obj)
console.info(output)
// { a: 2, c: 3 }Было бы здорово, если бы такая библиотека, как Лодаш, предлагала поддержку для этого.
Я бы использовал концепцию деструктуризации.
array.map((elem) => {
const {
id,
marketValuey,
marketValueySecond,
marketValueyThird,
asset: {key},
asset: {type}
} = elem;
return {
id,
marketValuey,
marketValueySecond,
marketValueyThird,
key,
type
}
})
для более подробной концепции деструктуризации см. - вложенная деструктуризация
Выглядит хорошо. Вы столкнулись с какой-либо проблемой?