У меня есть такой объект:
myObj = {
prop1: 'prop1_value',
prop2: 'prop2_value',
subObj: {
subProp1: 'subProp1_value',
subProp2: 'subProp2_value',
subProp3: 'subProp3_value',
subprop4: 'subProp4_value',
},
};
и такой массив:
myArr = [
'arrayVal_1',
'arrayVal_2',
'arrayVal_3',
'arrayVal_4',
];
Для контекста subObj и myArr всегда имеют одинаковую длину.
Я пытаюсь сопоставить каждое из значений из myArr со значениями subObj.
myObj будет выглядеть следующим образом:
myObj = {
prop1: 'prop1_value',
prop2: 'prop2_value',
subObj: {
subProp1: 'arrayVal_1',
subProp2: 'arrayVal_2',
subProp3: 'arrayVal_3',
subprop4: 'arrayVal_4',
},
};
Я мог бы вручную присвоить значения каждой клавише отдельно, но это выглядит неаккуратно. Я пробовал зацикливаться с Object.keys, Object.entries и Object.values на myObj, но просто не могу понять это. Спасибо.
Я действительно даже не рассматривал это, но это проблема. Мне нужно, чтобы значения массива и значения ключей совпадали в этом конкретном порядке.
Это означает, что в вашей исходной структуре данных есть недостаток. Когда данные должны поддерживать определенный порядок, вы должны использовать не простой (под)объект, а массив (пар или чего-либо, что хранит как свойство, так и значение). Ключи объекта могут иметь неожиданный порядок, когда они вставлены в другой последовательности или когда один из них является целым числом и т. д. Это сбивает с толку, и вы не будете первым, кто столкнется с «необъяснимыми» ошибками из-за этого.
Мне придется подумать об этом. Способ, которым я использую subObj в другом месте кода, заключается в двусторонней привязке значений к радио-вводам, значениями которых являются строки. Поскольку радиогруппы создаются динамически, мне понадобилась карта, чтобы отделить привязки друг от друга. Спасибо за наводку на этот вопрос.
@trincot Хотя, начиная с ES2015, порядок ключей объектов предсказуем.
@ Кейт, предсказуемо, но не тривиально, и на плохую практику можно положиться - в чем моя точка зрения. Кроме того, начиная с ES2015 все еще остаются неясности, которые были устранены только в более поздних версиях, и только в ЕС2020 полностью устранены.
Кроме того, невозможно добиться, чтобы ключ «4» отображался после ключом «А».
У @trincot было подобное обсуждение много лет назад, и все эти крайние случаи были обнаружены, но, глядя на ключи, которые использовал здесь оператор, все должно быть в порядке. Не говоря уже о том, что это идеально, но оператору, который должен реструктурировать весь свой код, может быть излишним.
Вы можете сделать это с Object.fromEntries
и Object.keys
следующим образом:
myObj.subObj = Object.fromEntries(Object.keys(myObj.subObj).map((k,i) => [k, myArr[i]]))
Имейте в виду, что в настоящее время нет никаких гарантий, поэтому вы можете проверить, подходят ли две структуры данных, прежде чем делать это.
Если у вас есть что-то, что вы можете упорядочить по ключам объекта, вы также можете использовать sort
, чтобы убедиться, что вы присваиваете правильные значения правильным ключам, потому что результирующий порядок Object.keys
не гарантируется.
myObj.subObj = Object.fromEntries(Object.keys(myObj.subObj)
.sort((a,b) => a.localeCompare(b)) //sort keys ascending by name
.map((k,i) => [k, myArr[i]]))
Отлично работает, но я думаю, что в аргументе метода карты отсутствует закрывающая скобка.
Используя Object#keys
и Array#forEach
:
const
myObj = {
prop1: 'prop1_value',
prop2: 'prop2_value',
subObj: { subProp1: 'subProp1_value', subProp2: 'subProp2_value', subProp3: 'subProp3_value', subprop4: 'subProp4_value' }
},
myArr = [ 'arrayVal_1', 'arrayVal_2', 'arrayVal_3', 'arrayVal_4' ];
const { subObj } = myObj;
Object.keys(subObj).forEach((prop, index) => { subObj[prop] = myArr[index] });
console.log(myObj);
Это отлично работает, но это злит eslint моей компании, ха-ха: eslint.org/docs/rules/no-return-assign
@dblinkhorn попробуйте обновленную версию
Счастливый Эслинт! Отличное решение, спасибо!
Вы хотите зациклить свои ключи и массив вместе. Один из способов — попробовать так:
const myObj = {
prop1: 'prop1_value',
prop2: 'prop2_value',
subObj: {
subProp1: 'subProp1_value',
subProp2: 'subProp2_value',
subProp3: 'subProp3_value',
subprop4: 'subProp4_value',
},
};
const myArr = ['arrayVal_1', 'arrayVal_2', 'arrayVal_3', 'arrayVal_4'];
const keys = Object.keys(myObj.subObj); // You should actually sort these according to myArr to ensure safety
for (let i = 0; i < myArr.length; i++) {
myObj.subObj[keys[i]] = myArr[i];
}
console.log(myObj);
Как вы определяете, какое подсвойство получает какое значение массива, когда порядок свойств в объекте — это то, на что вы не должны полагаться?