Home > front end >  javascript - how to remove all single entries in an array
javascript - how to remove all single entries in an array

Time:11-18

I have an array like this:

const data = [
  {"id": 3, "value": "a"},
  {"id": 3, "value": "b"},
  {"id": 4, "value": "a"},
  {"id": 8, "value": "d"},
  {"id": 1, "value": "d"},
  {"id": 2, "value": "d"},
  {"id": 5, "value": "z"},
  {"id": 8, "value": "h"},
  {"id": 8, "value": "b"},
]

and would like to delete all objects, where the value is not the same in one of the other objects. So, at the end I would like to have:

[
  {"id": 3, "value": "a"},
  {"id": 4, "value": "a"},
  {"id": 3, "value": "b"},
  {"id": 8, "value": "b"},
  {"id": 1, "value": "d"},
  {"id": 2, "value": "d"},
]

I tried several versions. How to check against something which you don´t know if it is there (later in the loop)? If I do check the list against itself in a loop, I am runing in the corner, that the array itself changes its length during the for loop... Is there a simple approach?

Thanks for any help!

CodePudding user response:

You need two passes in your array: the first one will count the number for each values, the second one will remove the objects with lone values:

function removeLoneValues(data) {
  const values = {}

  data.forEach(datum => {
    if (values[datum.value] === undefined) {
      values[datum.value] = 0
    }
    values[datum.value]  
  })

  data.filter(datum => {
    return values[datum.value] > 1
  })

  return data
}

CodePudding user response:

You can achieve it like this:-

const data = [
  {"id": 3, "value": "a"},
  {"id": 3, "value": "b"},
  {"id": 4, "value": "a"},
  {"id": 8, "value": "d"},
  {"id": 1, "value": "d"},
  {"id": 2, "value": "d"},
  {"id": 5, "value": "z"},
  {"id": 8, "value": "h"},
  {"id": 8, "value": "b"},
]

let reqOutput = [];
for (let i = 0; i < data.length; i  ) {
    if (data[i].value == "a") {
        reqOutput.push(data[i]);
    }
}
for (let i = 0; i < data.length; i  ) {
    if (data[i].value == "b") {
        reqOutput.push(data[i]);
    }
}
for (let i = 0; i < data.length; i  ) {
    if (data[i].value == "d") {
        reqOutput.push(data[i]);
    }
}

console.log(reqOutput);
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

You can use Array.prototype.indexOf and Array.prototype.lastIndexOf alongside Array.prototype.filter and Array.prototype.map to achieve this:

const data = [
  {"id": 3, "value": 'a'},
  {"id": 3, "value": 'b'},
  {"id": 4, "value": 'a'},
  {"id": 8, "value": 'd'},
  {"id": 1, "value": 'd'},
  {"id": 2, "value": 'd'},
  {"id": 5, "value": 'z'},
  {"id": 8, "value": 'h'},
  {"id": 8, "value": 'b'},
];

const values = data.map((el) => el.value);

const nonUniqueData = data.filter((el) => values.indexOf(el.value) !== values.lastIndexOf(el.value));
console.log(nonUniqueData);
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

This code works by first creating a mapped array of only values, then by checking that the results of indexOf and lastIndexOf when finding that value in the mapped array are different we can check that the array is not unique. This heuristic is then used in a filter function to create a new version of your data array with all elements containing unique values removed.

If you need to sort your array based on its value, you can use Array.prototype.sort to do that based on whatever your values are. I've converted them to strings here so the code snippet will run.

  • Related