Home > Blockchain >  Remove objects which are not common in all array of objects in multidimensional arrays
Remove objects which are not common in all array of objects in multidimensional arrays

Time:10-21

I have an array of array objects which is a multidimensional array where I need to remove the objects which are not common in the all array of objects

Here is the multidimensional array:

const array111 = [
  [{
      name: 'test1',
      parameters: {
        employee_number: 1
      }
    },
    {
      name: 'test2',
      parameters: {
        employee_number: 2
      }
    }, {
      name: 'test3',
      parameters: {
        employee_number: 4
      }
    },
    {
      name: 'test4',
      parameters: {
        employee_number: 5
      }
    },
    {
      name: 'test5',
      parameters: {
        employee_number: 6
      }
    }
  ],
  [{
      name: 'test1',
      parameters: {
        employee_number: 1
      }
    },
    {
      name: 'test4',
      parameters: {
        employee_number: 5
      }
    },
    {
      name: 'test5',
      parameters: {
        employee_number: 6
      }
    }
  ],
  [{
      name: 'test1',
      parameters: {
        employee_number: 1
      }
    },
    {
      name: 'test4',
      parameters: {
        employee_number: 4
      }
    },
    {
      name: 'test4',
      parameters: {
        employee_number: 5
      }
    },
    {
      name: 'test5',
      parameters: {
        employee_number: 6
      }
    }
  ],
  [{
      name: 'test1',
      parameters: {
        employee_number: 1
      }
    },
    {
      name: 'test4',
      parameters: {
        employee_number: 5
      }
    },
    {
      name: 'test5',
      parameters: {
        employee_number: 6
      }
    }
  ],
]
resultss = Object.values(array111.reduce((r, o) => {
  key = []
  key.push([...o.map(({
    parameters
  }) => parameters.employee_number)])
  r.push(key)
  return r;
}, []));
data = resultss.map(JSON.stringify).reverse().filter((e, i, a) => {
  return a.indexOf(e, i) === 1;
}).reverse().map(JSON.parse)

filteredRes = array111.map((element) => {
  element = element.filter(({
    parameters
  }) => data[0][0].some((val) => val === parameters.employee_number));
  return element;
})
console.log(filteredRes)
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

In the above array employee_number "1,5,6" are common in all arrays of objects and employee_number"2,4" should be removed which is not common in all arrays

The solution which I tried is giving correct results but as it is the lengthier way I want the smaller solution.

const array111 = [
  [{
      name: 'test1',
      parameters: {
        employee_number: 1
      }
    },
    {
      name: 'test4',
      parameters: {
        employee_number: 5
      }
    },
    {
      name: 'test5',
      parameters: {
        employee_number: 6
      }
    }
  ],
  [{
      name: 'test1',
      parameters: {
        employee_number: 1
      }
    },
    {
      name: 'test4',
      parameters: {
        employee_number: 5
      }
    },
    {
      name: 'test5',
      parameters: {
        employee_number: 6
      }
    }
  ],
  [{
      name: 'test1',
      parameters: {
        employee_number: 1
      }
    },
    {
      name: 'test4',
      parameters: {
        employee_number: 5
      }
    },
    {
      name: 'test5',
      parameters: {
        employee_number: 6
      }
    }
  ],
  [{
      name: 'test1',
      parameters: {
        employee_number: 1
      }
    },
    {
      name: 'test4',
      parameters: {
        employee_number: 5
      }
    },
    {
      name: 'test5',
      parameters: {
        employee_number: 6
      }
    }
  ],
]
 
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

Above is the O/P

CodePudding user response:

You can easily achieve the result using Set and Map

Using Set and Map

const array111 = [
  [
    {
      name: "test1",
      parameters: {
        employee_number: 1,
      },
    },
    {
      name: "test2",
      parameters: {
        employee_number: 2,
      },
    },
    {
      name: "test3",
      parameters: {
        employee_number: 4,
      },
    },
    {
      name: "test4",
      parameters: {
        employee_number: 5,
      },
    },
    {
      name: "test5",
      parameters: {
        employee_number: 6,
      },
    },
  ],
  [
    {
      name: "test1",
      parameters: {
        employee_number: 1,
      },
    },
    {
      name: "test4",
      parameters: {
        employee_number: 5,
      },
    },
    {
      name: "test5",
      parameters: {
        employee_number: 6,
      },
    },
  ],
  [
    {
      name: "test1",
      parameters: {
        employee_number: 1,
      },
    },
    {
      name: "test4",
      parameters: {
        employee_number: 5,
      },
    },
    {
      name: "test5",
      parameters: {
        employee_number: 6,
      },
    },
  ],
  [
    {
      name: "test1",
      parameters: {
        employee_number: 1,
      },
    },
    {
      name: "test4",
      parameters: {
        employee_number: 4,
      },
    },
    {
      name: "test4",
      parameters: {
        employee_number: 5,
      },
    },
    {
      name: "test5",
      parameters: {
        employee_number: 6,
      },
    },
  ],
];

const uniqueNamesFrequency = array111
  .map((arr) => Array.from(arr.reduce((acc, curr) => acc.add(curr.parameters.employee_number),new Set())))
  .reduce((acc, curr, i) => {
    curr.forEach((id) => acc.set(id, (acc.get(id) ?? 0)   1));
    return acc;
  }, new Map());

const result = array111.map((arr) =>arr.filter((o) => uniqueNamesFrequency.get(o.parameters.employee_number) === array111.length));

console.log(result);
/* This is not a part of answer. It is just to give the output fill height. So IGNORE IT */
.as-console-wrapper { max-height: 100% !important; top: 0; }
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

Wihout using Set

const array111 = [
  [
    {
      name: "test1",
      parameters: {
        employee_number: 1,
      },
    },
    {
      name: "test2",
      parameters: {
        employee_number: 2,
      },
    },
    {
      name: "test3",
      parameters: {
        employee_number: 4,
      },
    },
    {
      name: "test4",
      parameters: {
        employee_number: 5,
      },
    },
    {
      name: "test5",
      parameters: {
        employee_number: 6,
      },
    },
  ],
  [
    {
      name: "test1",
      parameters: {
        employee_number: 1,
      },
    },
    {
      name: "test4",
      parameters: {
        employee_number: 5,
      },
    },
    {
      name: "test5",
      parameters: {
        employee_number: 6,
      },
    },
  ],
  [
    {
      name: "test1",
      parameters: {
        employee_number: 1,
      },
    },
    {
      name: "test4",
      parameters: {
        employee_number: 5,
      },
    },
    {
      name: "test5",
      parameters: {
        employee_number: 6,
      },
    },
  ],
  [
    {
      name: "test1",
      parameters: {
        employee_number: 1,
      },
    },
    {
      name: "test4",
      parameters: {
        employee_number: 4,
      },
    },
    {
      name: "test4",
      parameters: {
        employee_number: 5,
      },
    },
    {
      name: "test5",
      parameters: {
        employee_number: 6,
      },
    },
  ],
];

const uniqueNamesFrequency = array111
  .map((arr) => Array.from( arr.reduce((acc, curr) => {
        if (!acc.includes(curr.parameters.employee_number))
          acc.push(curr.parameters.employee_number);
        return acc;
      }, [])))
  .reduce((acc, curr, i) => {
    curr.forEach((id) => acc.set(id, (acc.get(id) ?? 0)   1));
    return acc;
  }, new Map());

const result = array111.map((arr) => arr.filter( (o) => uniqueNamesFrequency.get(o.parameters.employee_number) === array111.length));

console.log(result);
/* This is not a part of answer. It is just to give the output fill height. So IGNORE IT */
.as-console-wrapper { max-height: 100% !important; top: 0; }
<iframe name="sif4" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

if you do not mind lodash library:

const _ = require('lodash');

const uniqOnly = (arr) => {
  const uniqPart = _.intersectionBy(...arr, (o) => o.parameters.employee_number);
  return = arr.map(() => [...commomPart]);
}

console.log(uniqOnly(array111))

// output:
[
  [
    { name: 'test1', parameters: [Object] },
    { name: 'test4', parameters: [Object] },
    { name: 'test5', parameters: [Object] }
  ],
  [
    { name: 'test1', parameters: [Object] },
    { name: 'test4', parameters: [Object] },
    { name: 'test5', parameters: [Object] }
  ],
  [
    { name: 'test1', parameters: [Object] },
    { name: 'test4', parameters: [Object] },
    { name: 'test5', parameters: [Object] }
  ],
  [
    { name: 'test1', parameters: [Object] },
    { name: 'test4', parameters: [Object] },
    { name: 'test5', parameters: [Object] }
  ]
]
  • Related