Home > Net >  Return nested array by object property
Return nested array by object property

Time:09-16

I have got an array of object: And would like to map it to another array witch structure should look like this:

const desireOutput = [
  { seq: 0, level: 1, code: '20', value: 'lorem', connectedByCode: [] },
  { seq: 2, level: 1, code: '30A', value: 'lorem', connectedByCode: [      
      { seq: 3, level: 2, code: '30A', value: 'lorem' },
      { seq: 4, level: 2, code: '30A', value: 'lorem' },
      { seq: 5, level: 2, code: '30A', value: 'lorem' }] },
  { seq: 8, level: 1, code: '40', value: 'lorem', connectedByCode: []  },
  { seq: 13, level: 1, code: '50', value: 'lorem', connectedByCode: []  },
  { seq: 15, level: 1, code: '60', value: 'lorem', connectedByCode: []  },
];

I was able to manage it by this code:

const array1 = [{
    seq: 0,
    level: 1,
    code: '20',
    value: 'lorem'
  },
  {
    seq: 2,
    level: 1,
    code: '30A',
    value: 'lorem'
  },
  {
    seq: 3,
    level: 2,
    code: '30A',
    value: 'lorem'
  },
  {
    seq: 4,
    level: 2,
    code: '30A',
    value: 'lorem'
  },
  {
    seq: 5,
    level: 2,
    code: '30A',
    value: 'lorem'
  },
  {
    seq: 8,
    level: 1,
    code: '40',
    value: 'lorem'
  },
  {
    seq: 13,
    level: 1,
    code: '50',
    value: 'lorem'
  },
  {
    seq: 15,
    level: 1,
    code: '60',
    value: 'lorem'
  },
];
const newTable = array1.filter(i => i.level === 1);
const level2 = array1.filter(i => i.level === 2);

level2.forEach(item => {
  const index = newTable.findIndex(i => i.code === item.code);

  newTable[index].connectedByCode = level2.filter(i => i.code === item.code);
});

I don't like that code so much to be honest. Is there any better way to do this?

CodePudding user response:

https://playcode.io/963588/

const array1 = [{
    seq: 0,
    level: 1,
    code: '20',
    value: 'lorem'
  },
  {
    seq: 2,
    level: 1,
    code: '30A',
    value: 'lorem'
  },
  {
    seq: 3,
    level: 2,
    code: '30A',
    value: 'lorem'
  },
  {
    seq: 4,
    level: 2,
    code: '30A',
    value: 'lorem'
  },
  {
    seq: 5,
    level: 2,
    code: '30A',
    value: 'lorem'
  },
  {
    seq: 8,
    level: 1,
    code: '40',
    value: 'lorem'
  },
  {
    seq: 13,
    level: 1,
    code: '50',
    value: 'lorem'
  },
  {
    seq: 15,
    level: 1,
    code: '60',
    value: 'lorem'
  },
];



const newTable = []
const level2 = []
const newTableCodes = []
const level2Codes = []

for(let [index, {level, code}]  of array1.entries()){
    if(level === 1) {
        newTable.push({...array1[index], connectedByCode:[]})
        newTableCodes.push(array1[index]['code'])
    }
    else {
        level2.push(array1[index]) 
        level2Codes.push(array1[index]['code'])
    }
}
// in order to save some iterations. Will only work if newTable code values are unique

const setLevel2 = new Set(level2Codes) // u can ignore this 

for(let [indexNew, valueNew] of newTableCodes.entries()){
    if(!setLevel2.has(valueNew)) continue // this also
    else setLevel2.delete(valueNew) // and this too
    for(let [index2, value2] of level2Codes.entries()){
        if(valueNew === value2) newTable[indexNew]['connectedByCode'].push(level2[index2])
    }
    
}


console.log(newTable)

Not sure if this is a much better approach. Atleast is another way to make it, hope it helps. (Set is a hashlist with no duplicated values)

CodePudding user response:

It depends on what you don't like or what you want to change in your code.

Do you want to make it faster or more generic ? Or is it just code style?

From what you shared, the code looks fine for me. Anyway, below is an example of how you can reformat your code a bit, see if you like it more or not.

An example:

const isRootItem = item => item.level === 1;
const isConnectedItem = item => item.level === 2;

const allConnectedItems = array1.filter(isConnectedItem);
const getConnectedItems = item => allConnectedItems.filter(connectedItem => connectedItem.code === item.code);

const items = array1
  .filter(isRootItem)
  .map(item => ({ ...item, connectedByCode: getConnectedItems(item) }));

Snippet:

const array1 = [{
    seq: 0,
    level: 1,
    code: '20',
    value: 'lorem'
  },
  {
    seq: 2,
    level: 1,
    code: '30A',
    value: 'lorem'
  },
  {
    seq: 3,
    level: 2,
    code: '30A',
    value: 'lorem'
  },
  {
    seq: 4,
    level: 2,
    code: '30A',
    value: 'lorem'
  },
  {
    seq: 5,
    level: 2,
    code: '30A',
    value: 'lorem'
  },
  {
    seq: 8,
    level: 1,
    code: '40',
    value: 'lorem'
  },
  {
    seq: 13,
    level: 1,
    code: '50',
    value: 'lorem'
  },
  {
    seq: 15,
    level: 1,
    code: '60',
    value: 'lorem'
  },
];

const isRootItem = item => item.level === 1;
const isConnectedItem = item => item.level === 2;

const allConnectedItems = array1.filter(isConnectedItem);
const getConnectedItems = item => allConnectedItems.filter(connectedItem => connectedItem.code === item.code);

const items = array1
  .filter(isRootItem)
  .map(item => ({ ...item, connectedByCode: getConnectedItems(item) }));

console.log(items);

  • Related