简体   繁体   中英

Match element with array of object and push to new Array

Suppose I have an array of object as,

const attachmentData = [{name: 'Suman Baidh',attachment: ["123","456"]},
                        {name: 'John Sigma',attachment: ["789","101112]},
                        {name: 'Binay', attachment: ["131415","161718","192021]}]

And another array of object as,

const attachmentDetail = [{"id":"123",details:{"cost":10,"quantity":20}},
                          {"id":"456",details: {"cost":15,"quantity":28}},
                          {"id":"789",details:{"cost":4,"quantity":9}},
                          {"id":"101112",details:{"cost":40,"quantity":2}},
                          {"id":"131415",details:{"cost":12,"quantity":9}},
                          {"id":"161718",details:{"cost":45,"quantity":2}},
                          {"id":"192021",details:{"cost":120,"quantity":1}}]

I want the O/P as: Such that the id which is matched with attachmentDetail also has name along with it and pushed to new array.

      [{"name":"Suman Baidh","id":"123","cost":10,"quantity":20},
       {"name":"Suman Baidh","id":"456","cost":15,"quantity":28},
       {"name":"John Sigma","id":"789","cost":4,"quantity":9} ,
       {"name":"John Sigma","id":"101112","cost":40,"quantity":2}, 
       {"name":"Binay","id":"131415","cost":12,"quantity":9}, 
       {"name":"Binay","id":"161718","cost":45,"quantity":2}, 
       {"name":"Binay","id":"192021","cost":120,"quantity":1}]

For this I tried as,

let newArray = []
for(let i = 0;i<attachmentData.length;i++)}{
    for(let j = 0;j<attachmentData[i].attachment.length;j++){
        if(attachmentData[i].attachment[j] == attachmentDetail.id){
            newArray.push(...attachmentData[i], ... attachmentData[i].attachment[j]
        }
    }
}

On console.log(newArray) , its giving me not the answer I wanted. 

If anyone needs any further information, please let me know. Any suggestion would be really helpful.

The problem is in the line:

if (attachmentData[i].attachment[j] === attachmentDetail.id) {

Here attachmentDetail is an array. To access its element you need to use attachmentDetail[index].id .

You will need to loop through it to match the id from attachmentData .

Try this,

 const attachmentData = [ { name: "Suman Baidh", attachment: ["123", "456"] }, { name: "John Sigma", attachment: ["789", "101112"] }, { name: "Binay", attachment: ["131415", "161718", "192021"] }, ]; const attachmentDetail = [ { id: "123", details: { cost: 10, quantity: 20 } }, { id: "456", details: { cost: 15, quantity: 28 } }, { id: "789", details: { cost: 4, quantity: 9 } }, { id: "101112", details: { cost: 40, quantity: 2 } }, { id: "131415", details: { cost: 12, quantity: 9 } }, { id: "161718", details: { cost: 45, quantity: 2 } }, { id: "192021", details: { cost: 120, quantity: 1 } }, ]; let newArr = []; attachmentData.forEach(({name, attachment}) => { attachment.forEach((id) => { const { details: { cost, quantity } } = attachmentDetail.find((item) => item.id === id) newArr.push({ name, id, cost, quantity}) }) }) console.log(newArr)

NOTE: Try to use find , map , forEach , filter functions to simplify the for loop whenever possible.

const attachmentData = [{name: 'Suman Baidh', attachment: ["123", "456"]},
    {name: 'John Sigma', attachment: ["789", "101112"]},
    {name: 'Binay', attachment: ["131415", "161718", "192021"]}];


const attachmentDetail = [{"id": "123", details: {"cost": 10, "quantity": 20}},
    {"id": "456", details: {"cost": 15, "quantity": 28}},
    {"id": "789", details: {"cost": 4, "quantity": 9}},
    {"id": "101112", details: {"cost": 40, "quantity": 2}},
    {"id": "131415", details: {"cost": 12, "quantity": 9}},
    {"id": "161718", details: {"cost": 45, "quantity": 2}},
    {"id": "192021", details: {"cost": 120, "quantity": 1}}];

let newArray = []
for (let i = 0; i < attachmentData.length; i++) {
    for (let j = 0; j < attachmentData[i].attachment.length; j++) {
        for (let k = 0; k < attachmentDetail.length; ++k) {
            if (attachmentData[i].attachment[j] === attachmentDetail[k].id) {
                newArray.push({
                    name: attachmentData[i].name,
                    id: attachmentDetail[k].id,
                    ...attachmentDetail[k].details
                });
            }
        }
    }
}

console.log(newArray);

Or

const attachmentData = [{name: 'Suman Baidh', attachment: ["123", "456"]},
    {name: 'John Sigma', attachment: ["789", "101112"]},
    {name: 'Binay', attachment: ["131415", "161718", "192021"]}];


const attachmentDetail = [{"id": "123", details: {"cost": 10, "quantity": 20}},
    {"id": "456", details: {"cost": 15, "quantity": 28}},
    {"id": "789", details: {"cost": 4, "quantity": 9}},
    {"id": "101112", details: {"cost": 40, "quantity": 2}},
    {"id": "131415", details: {"cost": 12, "quantity": 9}},
    {"id": "161718", details: {"cost": 45, "quantity": 2}},
    {"id": "192021", details: {"cost": 120, "quantity": 1}}];

const newArray = attachmentDetail.map(x => ({
    name: attachmentData.filter(y => y.attachment.includes(x.id))[0].name,
    id: x.id, ...x.details
}));
console.log(newArray);

Output

[
    { name: 'Suman Baidh', id: '123', cost: 10, quantity: 20 },
    { name: 'Suman Baidh', id: '456', cost: 15, quantity: 28 },
    { name: 'John Sigma', id: '789', cost: 4, quantity: 9 },
    { name: 'John Sigma', id: '101112', cost: 40, quantity: 2 },
    { name: 'Binay', id: '131415', cost: 12, quantity: 9 },
    { name: 'Binay', id: '161718', cost: 45, quantity: 2 },
    { name: 'Binay', id: '192021', cost: 120, quantity: 1 }
]

I think that something like this will work!

const attachmentData = [
  { name: "Suman Baidh", attachment: ["123", "456"] },
  { name: "John Sigma", attachment: ["789", "101112"] },
  { name: "Binay", attachment: ["131415", "161718", "192021"] },
];

const attachmentDetail = [
  { id: "123", details: { cost: 10, quantity: 20 } },
  { id: "456", details: { cost: 15, quantity: 28 } },
  { id: "789", details: { cost: 4, quantity: 9 } },
  { id: "101112", details: { cost: 40, quantity: 2 } },
  { id: "131415", details: { cost: 12, quantity: 9 } },
  { id: "161718", details: { cost: 45, quantity: 2 } },
  { id: "192021", details: { cost: 120, quantity: 1 } },
];


const newArray = attachmentDetail.map((detail) => {
    const data = attachmentData.find((data) => data.attachment.includes(detail.id));
    return {name: data.name, id: detail.id, ...detail.details}
})

If we want to deal with two arrays(specially for large sets of data), It's always good to convert one array to object(hash) and iterate over the other to find the matching.

 const attachmentData = [{name: 'Suman Baidh',attachment: ["123","456"]}, {name: 'John Sigma',attachment: ["789","101112"]}, {name: 'Binay', attachment: ["131415","161718","192021"]}] const attachmentDetail = [{"id":"123",details:{"cost":10,"quantity":20}}, {"id":"456",details: {"cost":15,"quantity":28}}, {"id":"789",details:{"cost":4,"quantity":9}}, {"id":"101112",details:{"cost":40,"quantity":2}}, {"id":"131415",details:{"cost":12,"quantity":9}}, {"id":"161718",details:{"cost":45,"quantity":2}}, {"id":"192021",details:{"cost":120,"quantity":1}}]; function customMerge(data, attachments) { const hashById = attachments.reduce((acc, ele) => { acc[ele.id] = ele; return acc; }, {}); return data.reduce((acc, {attachment, name}) => { return acc.concat(attachment.map(id => ({name, id, details: hashById[id].details}))); },[]); } console.log(customMerge(attachmentData, attachmentDetail))

  const attachmentData = [
        { name: 'Suman Baidh', attachment: [ '123', '456' ] },
        { name: 'John Sigma', attachment: [ '789', '101112' ] },
        { name: 'Binay', attachment: [ '131415', '161718', '192021' ] },
    ];
    
    const attachmentDetail = [
        { id: '123', details: { cost: 10, quantity: 20 } },
        { id: '456', details: { cost: 15, quantity: 28 } },
        { id: '789', details: { cost: 4, quantity: 9 } },
        { id: '101112', details: { cost: 40, quantity: 2 } },
        { id: '131415', details: { cost: 12, quantity: 9 } },
        { id: '161718', details: { cost: 45, quantity: 2 } },
        { id: '192021', details: { cost: 120, quantity: 1 } },
    ];
    
    const newArray = [];
    
    for (let i = 0; i < attachmentData.length; i++) {
        const { attachment } = attachmentData[i];
    
        for (let j = 0; j < attachment.length; j++) {
            attachmentDetail.some(element => {
                if (element.id === attachment[j]) {
                    newArray.push({ name: attachmentData[i].name, ...element });
                    return true;
                }
            });
        }
    }
    
    console.log(newArray);

You can first create a Map whose keys are the attachment ids and value is the name corresponding to that attachment.

Then loop over attachmentDetail array and just add the name using the Map created.

 const attachmentData = [{ name: "Suman Baidh", attachment: ["123", "456"] }, { name: "John Sigma", attachment: ["789", "101112"] }, { name: "Binay", attachment: ["131415", "161718", "192021"] }], attachmentDetail = [{ id: "123", details: { cost: 10, quantity: 20 } }, { id: "456", details: { cost: 15, quantity: 28 } }, { id: "789", details: { cost: 4, quantity: 9 } }, { id: "101112", details: { cost: 40, quantity: 2 } }, { id: "131415", details: { cost: 12, quantity: 9 } }, { id: "161718", details: { cost: 45, quantity: 2 } }, { id: "192021", details: { cost: 120, quantity: 1 } }], map = attachmentData.reduce((m, o) => (o.attachment.map((a) => m.set(a, o.name)), m), new Map()), res = attachmentDetail.map(({ id, details }) => (name => ({ id, name, ...details }))(map.get(id))); console.log(res);

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