Дублируйте элемент в массиве на основе вложенных элементов, прикрепленных к одному из ключей этого элемента в JavaScript

#javascript #arrays #for-loop #object

Вопрос:

У меня есть массив объектов, который выглядит следующим образом

 {name:"name1", phoneNumbers:[{"home":"0700 999999"}, {"mobile":"0700 999998"}]}, {name:"name2", phoneNumbers:[{"home":"0700 999991"}, {"mobile":"0700 999995"}, fax:"48289299200"]}, {name:"name3", phoneNumbers:[{"home":"0700 999992"}, {"mobile":"0700 999988"}]} ]  

То, чего я хочу достичь, — это что-то вроде этого

 {name:"name1", phoneNumbers:[{"home":"0700 999999"}]}, {name:"name1", phoneNumbers:[{"mobile":"0700 999998"}]}, {name:"name2", phoneNumbers:[{"home":"0700 999991"}]}, {name:"name2", phoneNumbers:[{"mobile":"0700 999995"}]}, {name:"name2", phoneNumbers:[{fax:"48289299200"}]}, ... ]  

Таким образом, каждое имя будет снова указано с прикрепленными к нему контактными средствами.

Я подошел к этому пути, и мне было сложно заставить решение работать, так как внешний цикл не ждет исчерпывающего выполнения внутреннего цикла, прежде чем он сможет перейти к следующему индексу:

 const doSomeRecursion=(arr, i, result)=gt;{  for(let j=0; jlt;arr[i]["phoneNumbers"].length; j  ){   arr[i]["phoneNumbers"]=[arr[i]["phoneNumbers"][j]]  result.push(arr[i])  }  }   const getAllContacts=(contacts)=gt;{   const reconstructedContacts=[]  for(let i=0; ilt;contacts.length; i  ){  doSomeRecursion(contacts, i, reconstructedContacts)  }   return reconstructedContacts }  

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

Редактировать: Спасибо, @T. J. Краудер, я исправил вопрос и завернул его в функцию.

Комментарии:

1. Первый блок кода содержит синтаксические ошибки. Невозможно определить, какова ваша исходная структура. Пожалуйста, обновите вопрос, указав правильную начальную структуру.

2. Спасибо, @Ти Джей Краудер. Я обновил вопрос

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

Ответ №1:

Начальный блок кода в вашем вопросе содержит множество синтаксических ошибок, поэтому трудно быть уверенным в том, какова ваша начальная структура, но, исходя из разумных предположений, здесь вообще нет необходимости в рекурсии, просто вложенные циклы:

 const result = []; for (const {name, phoneNumbers} of original) {  for (const number of phoneNumbers) {  result.push({name, phoneNumbers: number});  } }  

Живой Пример:

 const original = [  {  name: "name1",  phoneNumbers: [  { "home": "0700 999999" },  { "mobile": "0700 999998" }  ]  },  {  name: "name2",  phoneNumbers: [  { "home": "0700 999991" },  { "mobile": "0700 999995" },  {fax: "48289299200"}  ]  },  {  name: "name3",  phoneNumbers: [  { "home": "0700 999992" },  { "mobile": "0700 999988" }  ]  } ];  const result = []; for (const {name, phoneNumbers} of original) {  for (const number of phoneNumbers) {  result.push({name, phoneNumbers: number});  } }  console.log(JSON.stringify(result, null, 4)); 

Комментарии:

1. Спасибо, @Ти Джей Краудер. Это решение отвечает на мой вопрос.

Ответ №2:

Вы также можете сделать это, используя комбинацию flatMap() и map()

 const data = [  {name:"name1", phoneNumbers:[{"home":"0700 999999"}, {"mobile":"0700 999998"}]},   {name:"name2", phoneNumbers:[{"home":"0700 999991"}, {"mobile":"0700 999995"},   {"fax":"48289299200"}]},  {name:"name3", phoneNumbers:[{"home":"0700 999992"}, {"mobile":"0700 999988"}]} ];  const result = data.flatMap((n) =gt; {  return n.phoneNumbers.map((pn) =gt; {  return { name: n.name, phoneNumbers: [pn] }  }); });  console.log(result); 

Комментарии:

1. Спасибо @axtck, это первый раз, когда я узнаю о flatMap. Позвольте мне подробнее прочитать об этом и о сложности времени.