简体   繁体   中英

Javascript : Create a new array of objects(B) from an array of objects(A) associated with each other

Since yesterday, I can solve my algorythm problem.

I know that the title is not clear, so I will try to explain as clearly as possible what I have in mind.

What I want is to build from a table of objects(A) a new table of objects(B).

The array of objects (A) looks like this:

{
  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 I want is for the object array(B) to look like this:

{
  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"
    }
  ]
}

For the moment the only piece of code that comes closest to my goal is the following (everything else went to the trash):

 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'

Then I can't create an array of "link" objects associated to the main "id".

Someone can help me?

Thanks,

Sam.

This should work, Please confirm if you've issues and please also modify the variable names as need. ( It's a greedy solution and I have done no optimization )

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

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

You could get the id first and then build the wanted nested arrays.

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

Another approach with a single loop with a closure over a hash table, which collects the values later.

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

Hope this will solve your problem:

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

I hope this helps you:

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

You can leverage the power of the array methods map and find to transform the first array into the wished format.

The Array.map method is used to iterate and transform each child of the original array.

The Array.find method is used to iterate through another (or in this case the same) array in order to find a child inside it.

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

To decorticate what happens here:

  1. We loop through the arrayA Array and thereby create a new array to which each child is applied a transformation
const arraB = arrayA.map(functionTransformingEachChild)
  1. At each iteration, we copy the properties of the child of the current iteration and paste it into a new object (using the spread operator)
return {
    ...childInCurrentIteration
}
  1. We reassing the link proprety with a new array that is itself created with the map method
return {
    ...childInCurrentIteration,
    link: childInCurrentIteration.link.map(otherFunctionTransformingEachChild)
}
  1. When transforming each child of the link array, we find the object { id: "REC-002", text: "Instagram", ... } in the orignial Array arrayA using the key string of the current iteration (eg. "REC-002")
mapArrayAChild.link.map(
    (mapLinkChild) => {
        const linkObject = arrayA.find(
            (linkKeyStringInCurrentIteration) => {
                return linkKeyStringInCurrentIteration.key === mapLinkChild
            }
        )
        // ...
    }
)
  1. We return a new object (instead of the string that was previously part of the link array) and iclude the properties we need.
return {
    key: linkObject.id,
    text: linkObject.text
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM