Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to remove all combination with the same element in subarray from array?

I have this array

[[1,2,3],[4,1,6],[1,3,2],[1,2,4],[3,1,2],[4,6,1],[9,9,9]]

and I want a function that do this:

[[1,2,3],[4,1,6],[1,2,4],[9,9,9]].

This function removes all subarray with the same value.

I thought about a filter like this

.filter(el => el.filter(value => array2.includes(value)))

But I don't think it will work.

PS: I use node.js

EDIT: Weirdly, many of your answer work PERFECTLY with the example, but doesn't work in my true program... In fact I work with object instead of number. Like this: [[obj,obj,obj],[obj,obj,obj],[obj,obj,obj]]. But I don't know why it's work with number but not object...

EDIT2: I give now the minimal example, this object:

Note the actual array can have 20,000 items

  [
      [
        { name: 'Dofawa', item_type: 'Dofus', level: 6 },
        {
          name: 'Dofus Cawotte',
          item_type: 'Dofus',
          level: 6
        },
        {
          name: 'Dofus Kaliptus',
          item_type: 'Dofus',
          level: 6
        }
      ],
      [
        { name: 'Dofawa', item_type: 'Dofus', level: 6 },
        {
          name: 'Dofus Emeraude',
          item_type: 'Dofus',
          level: 6
        },
        {
          name: 'Dofus Ocre',
          item_type: 'Dofus',
          level: 6
        }
      ],
      [
        { name: 'Dofawa', item_type: 'Dofus', level: 6 },
        {
          name: 'Dofus Kaliptus',
          item_type: 'Dofus',
          level: 6
        },
        {
          name: 'Dofus Cawotte',
          item_type: 'Dofus',
          level: 6
        }
      ],
      [
        {
          name: 'Dofus Cawotte',
          item_type: 'Dofus',
          level: 6
        },
        {
          name: 'Dofus Kaliptus',
          item_type: 'Dofus',
          level: 6
        },
        { name: 'Dofawa', item_type: 'Dofus', level: 6 }
      ]
  ]

should give this object:

  [
      [
        { name: 'Dofawa', item_type: 'Dofus', level: 6 },
        {
          name: 'Dofus Cawotte',
          item_type: 'Dofus',
          level: 6
        },
        {
          name: 'Dofus Kaliptus',
          item_type: 'Dofus',
          level: 6
        }
      ],
      [
        { name: 'Dofawa', item_type: 'Dofus', level: 6 },
        {
          name: 'Dofus Emeraude',
          item_type: 'Dofus',
          level: 6
        },
        {
          name: 'Dofus Ocre',
          item_type: 'Dofus',
          level: 6
        }
      ]
  ]
like image 664
bosskay972 Avatar asked Dec 13 '19 22:12

bosskay972


1 Answers

By having aaray with objects and this objects have the same order of the keys, you could get each object as single JSON string and sort the array of JSONs and join this strings to a single string and take this string as value for checking the uniqueness witn a Set.

const
    normalize = v => v.map(o => JSON.stringify(o)).sort().join('|'),
    filterWithSet = s => v => (n => !s.has(n) && s.add(n))(normalize(v)),
    data = [[{ name: 'Dofawa', item_type: 'Dofus', level: 6 }, { name: 'Dofus Cawotte', item_type: 'Dofus', level: 6 }, { name: 'Dofus Kaliptus', item_type: 'Dofus', level: 6 }], [{ name: 'Dofawa', item_type: 'Dofus', level: 6 }, { name: 'Dofus Emeraude', item_type: 'Dofus', level: 6 }, { name: 'Dofus Ocre', item_type: 'Dofus', level: 6 }], [{ name: 'Dofawa', item_type: 'Dofus', level: 6 }, { name: 'Dofus Kaliptus', item_type: 'Dofus', level: 6 }, { name: 'Dofus Cawotte', item_type: 'Dofus', level: 6 }], [{ name: 'Dofus Cawotte', item_type: 'Dofus', level: 6 }, { name: 'Dofus Kaliptus', item_type: 'Dofus', level: 6 }, { name: 'Dofawa', item_type: 'Dofus', level: 6 }]],
    unique = data.filter(filterWithSet(new Set));

console.log(unique);
.as-console-wrapper { max-height: 100% !important; top: 0; }
like image 180
Nina Scholz Avatar answered Sep 20 '22 17:09

Nina Scholz