Javascript: создать новый массив объектов (B) из массива объектов (A), связанных друг с другом. - PullRequest
1 голос
/ 18 июня 2020

Со вчерашнего дня я могу решить свою проблему с алгоритмом.

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

Я хочу построить из таблицы объектов (A) новую таблицу объектов (B).

Массив объектов (A) выглядит так:

{
  id : "REC-001",
  text: "Facebook",
  link: ["REC-002", "REC-003"]
},
{
  id : "REC-002",
  text: "Instagram",
  link: ["REC-003"]
},
{
  id : "REC-003",
  text: "Snapshat",
  link: ["REC-001", "REC-002"]
}

What Я хочу, чтобы массив объектов (B) выглядел так:

{
  id : "REC-001",
  text: "Facebook",
  link: [
    {
      key: "REC-002",
      text: "Instagram"
    },
    {
      key: "REC-003",
      text: "Snapshat"
    }
  ]
},
{
  id : "REC-002",
  text: "Instagram",
  link: [
    {
      key: "REC-003",
      text: "Snapshat"
    }
  ]
},
{
  id : "REC-003",
  text: "Snapshat",
  link: [
    {
      key: "REC-001",
      text: "Facebook"
    },
    {
      key: "REC-002",
      text: "Instagram"
    }
  ]
}

На данный момент единственный фрагмент кода, который ближе всего подходит к моей цели, - это следующий (все остальное перешло в tra sh):

 for (let i = 0; i < objectA.length; i++) {
   for (let j = 0; j < objectA[i].link.length; j++) {
     console.log(i, j, objectA[i].link[j])
   };
 };

console.log:

0 0 'REC-002'
0 1 'REC-003'
1 0 'REC-003'
2 0 'REC-001'
2 1 'REC-002'

Тогда я не могу создать массив объектов «ссылки», связанных с основным «id».

Кто-нибудь может мне помочь?

Спасибо,

Сэм.

Ответы [ 6 ]

2 голосов
/ 18 июня 2020

Надеюсь, это решит вашу проблему:

let a = [{
  id : "REC-001",
  text: "Facebook",
  link: ["REC-002", "REC-003"]
},
{
  id : "REC-002",
  text: "Instagram",
  link: ["REC-003"]
},
{
  id : "REC-003",
  text: "Snapshat",
  link: ["REC-001", "REC-002"]
}];

let b = a.map( value => {
	return {
  	...value,
    link: [{key: value.link[0], text: 'Instagram'}, {key: value.link[1], text: 'Facebook'}]
  }
});

console.log(b);
2 голосов
/ 18 июня 2020

Вы можете сначала получить id, а затем построить нужные вложенные массивы.

var data = [{ id : "REC-001", text: "Facebook", link: ["REC-002", "REC-003"] }, { id : "REC-002", text: "Instagram", link: ["REC-003"] }, { id : "REC-003", text: "Snapshat", link: ["REC-001", "REC-002"] }],
    ids = data.reduce((m, { id: key, text }) => m.set(key, { key, text }), new Map),
    result = data.map(o => ({ ...o, link: o.link.map(id => ids.get(id)) }));
    
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Другой подход с одним l oop с закрытием над таблицей ha sh, которая собирает значения позже.

var data = [{ id : "REC-001", text: "Facebook", link: ["REC-002", "REC-003"] }, { id : "REC-002", text: "Instagram", link: ["REC-003"] }, { id : "REC-003", text: "Snapshat", link: ["REC-001", "REC-002"] }],
    result = data.map(
        (m => o => (
            Object.assign(m[o.id] = m[o.id] || {}, { key: o.id, text: o.text }),
            { ...o, link: o.link.map(id => m[id] = m[id] || {}) })
        )
        ({})
    );
    
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
2 голосов
/ 18 июня 2020

var arrA = [
  {
    id : "REC-001",
    text: "Facebook",
    link: ["REC-002", "REC-003"]
  },
  {
    id : "REC-002",
    text: "Instagram",
    link: ["REC-003"]
  },
  {
    id : "REC-003",
    text: "Snapshat",
    link: ["REC-001", "REC-002"]
  }
];

var arrB = arrA.map(itemA => ({
  id: itemA.id,
  text: itemA.text,
  link: itemA.link.map(l => {
    var foo = arrA.find(a => a.id === l);
    return {
      key: foo.id,
      text: foo.text
    };
  })
}));

console.log(arrB);
2 голосов
/ 18 июня 2020

Это должно сработать. Пожалуйста, подтвердите, есть ли у вас проблемы, и при необходимости измените имена переменных. (Это жадное решение, и я не делал никакой оптимизации)

 var d = [{
      id : "REC-001",
      text: "Facebook",
      link: ["REC-002", "REC-003"]
    },
    {
      id : "REC-002",
      text: "Instagram",
      link: ["REC-003"]
    },
    {
      id : "REC-003",
      text: "Snapshat",
      link: ["REC-001", "REC-002"]
    }];
    
    d.forEach(function(key){
      let newLink = [];
      key.link.forEach(function(linkData){
        d.forEach(function(obj){
          if(linkData === obj.id){
            newLink.push({key : obj.id, text : obj.text });
          }
        });
         key.link = newLink;
      });
    });
    
    console.log(d);
1 голос
/ 18 июня 2020

Вы можете использовать возможности методов массива map и find для преобразования первого массива в желаемый формат.

Метод Array.map используется для итерации и преобразования каждого дочернего элемента исходный массив.

Метод Array.find используется для перебора другого (или в данном случае того же самого) массива, чтобы найти дочерний элемент внутри него.

const arrayA = [
	{
		id: 'REC-001',
		text: 'Facebook',
		link: ['REC-002', 'REC-003'],
	},
	{
		id: 'REC-002',
		text: 'Instagram',
		link: ['REC-003'],
	},
	{
		id: 'REC-003',
		text: 'Snapshat',
		link: ['REC-001', 'REC-002'],
	},
]

const arrayB = arrayA.map((mapArrayAChild) => {
	return {
		...mapArrayAChild, // copy properties from mapArrayAChild into the new object
		link: mapArrayAChild.link.map((mapLinkChild) => {
			const linkObject = arrayA.find((findLinkChild) => {
				return findLinkChild.id === mapLinkChild
			}) // Find which child of arrayA has the key corresponding to each child of the current's link array
			return {
				key: linkObject.id,
				text: linkObject.text,
			}
		}),
	}
})

console.log(JSON.stringify(arrayB, null, '\t'))

Чтобы декортировать то, что здесь происходит:

  1. Мы l oop через массив arrayA и тем самым создаем новый массив, в котором каждый дочернему элементу применяется преобразование
const arraB = arrayA.map(functionTransformingEachChild)
На каждой итерации мы копируем свойства дочернего элемента текущей итерации и вставляем его в новый объект (с помощью оператора распространения)
return {
    ...childInCurrentIteration
}
Мы изменяем свойство ссылки с помощью нового массива, который сам создается с помощью метода map
return {
    ...childInCurrentIteration,
    link: childInCurrentIteration.link.map(otherFunctionTransformingEachChild)
}
При преобразовании каждого дочернего элемента массива ссылок мы находим объект { id: "REC-002", text: "Instagram", ... } в исходном массиве arrayA, используя ключевую строку текущей итерации (например, «RE C -002»)
mapArrayAChild.link.map(
    (mapLinkChild) => {
        const linkObject = arrayA.find(
            (linkKeyStringInCurrentIteration) => {
                return linkKeyStringInCurrentIteration.key === mapLinkChild
            }
        )
        // ...
    }
)
Мы возвращаем новый объект (вместо строки, которая ранее была частью массива link) и включаем нужные нам свойства.
return {
    key: linkObject.id,
    text: linkObject.text
}
1 голос
/ 18 июня 2020

Надеюсь, это вам поможет:

var ArrayA = [{
  id : "REC-001",
  text: "Facebook",
  link: ["REC-002", "REC-003"]
},
{
  id : "REC-002",
  text: "Instagram",
  link: ["REC-003"]
},
{
  id : "REC-003",
  text: "Snapshat",
  link: ["REC-001", "REC-002"]
}]

function getArrayB(array) {
  const formatLink = (key) => ({
    key,
    text: array.find(el => el.id === key).text
  });

  return array.map((item) => (
    item.link ? { ...item, link: item.link.map(formatLink) } : item
  ));
}

console.log(getArrayB(ArrayA));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...