Сопоставьте значения массива со значениями ключа объекта

У меня есть такой объект:

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, но просто не могу понять это. Спасибо.

Как вы определяете, какое подсвойство получает какое значение массива, когда порядок свойств в объекте — это то, на что вы не должны полагаться?

trincot 09.04.2022 09:15

Я действительно даже не рассматривал это, но это проблема. Мне нужно, чтобы значения массива и значения ключей совпадали в этом конкретном порядке.

dblinkhorn 09.04.2022 09:18

Это означает, что в вашей исходной структуре данных есть недостаток. Когда данные должны поддерживать определенный порядок, вы должны использовать не простой (под)объект, а массив (пар или чего-либо, что хранит как свойство, так и значение). Ключи объекта могут иметь неожиданный порядок, когда они вставлены в другой последовательности или когда один из них является целым числом и т. д. Это сбивает с толку, и вы не будете первым, кто столкнется с «необъяснимыми» ошибками из-за этого.

trincot 09.04.2022 09:19

Мне придется подумать об этом. Способ, которым я использую subObj в другом месте кода, заключается в двусторонней привязке значений к радио-вводам, значениями которых являются строки. Поскольку радиогруппы создаются динамически, мне понадобилась карта, чтобы отделить привязки друг от друга. Спасибо за наводку на этот вопрос.

dblinkhorn 09.04.2022 09:23

@trincot Хотя, начиная с ES2015, порядок ключей объектов предсказуем.

Keith 09.04.2022 09:27

@ Кейт, предсказуемо, но не тривиально, и на плохую практику можно положиться - в чем моя точка зрения. Кроме того, начиная с ES2015 все еще остаются неясности, которые были устранены только в более поздних версиях, и только в ЕС2020 полностью устранены.

trincot 09.04.2022 09:34

Кроме того, невозможно добиться, чтобы ключ «4» отображался после ключом «А».

trincot 09.04.2022 09:40

У @trincot было подобное обсуждение много лет назад, и все эти крайние случаи были обнаружены, но, глядя на ключи, которые использовал здесь оператор, все должно быть в порядке. Не говоря уже о том, что это идеально, но оператору, который должен реструктурировать весь свой код, может быть излишним.

Keith 09.04.2022 09:46
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
Четыре эффективных способа центрирования блочных элементов в CSS
Четыре эффективных способа центрирования блочных элементов в CSS
У каждого из нас бывали случаи, когда нам нужно отцентрировать блочный элемент, но мы не знаем, как это сделать. Даже если мы реализуем какой-то...
2
8
56
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вы можете сделать это с 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]]))

Отлично работает, но я думаю, что в аргументе метода карты отсутствует закрывающая скобка.

dblinkhorn 09.04.2022 09:48
Ответ принят как подходящий

Используя 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 09.04.2022 09:45

@dblinkhorn попробуйте обновленную версию

Majed Badawi 09.04.2022 09:46

Счастливый Эслинт! Отличное решение, спасибо!

dblinkhorn 09.04.2022 09:50

Вы хотите зациклить свои ключи и массив вместе. Один из способов — попробовать так:

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

Другие вопросы по теме