0

I want to write code, that iterates through a array and removes the duplicates. A duplicate should have the same values in all object-properties.

My array looks like this:

[ { name: 'Romeo Minnock', semester: 12 },
  { name: 'Romeo Minnock', semester: 8 },
  { name: 'Gideon Heinemann', semester: 19 },
  { name: 'Gideon Heinemann', semester: 1 },
  { name: 'Gideon Heinemann', semester: 19 },
  { name: 'Gideon Heinemann', semester: 12 },
  { name: 'Brant Colegrove', semester: 3 },
  { name: 'Brant Colegrove', semester: 17 },
  { name: 'Gideon Heinemann', semester: 1 },
  { name: 'Gideon Heinemann', semester: 12 } ]

Now I want to remove the students that have the same values in name and semester. But my code just outputs an empty array like this: [] Is something wrong with my if-condition?

for( k = 0; k < sameNameStudent.length; k++){
    for( l = k + 1; l < sameNameStudent.length; l++){
        if(sameNameStudent[k].semester == sameNameStudent[l].semester){
            sameNameStudent.splice(sameNameStudent[l])
        }
    }
}    

console.log(sameNameStudent);
Constantin Groß
  • 10,719
  • 4
  • 24
  • 50
ryanmitchell
  • 13
  • 1
  • 3
  • 1
    I am curious -- even though removing duplicate elements from an array is a legitimate thing to do -- where does your array come from that it contains duplicate values? Perhaps your data query wasn't really what it should have been? – Armen Michaeli Nov 22 '19 at 18:38
  • another solution to this problem https://stackoverflow.com/questions/50729508/removing-duplicate-objects-from-an-array/50729724#50729724 – Henrique Viana Nov 22 '19 at 18:58

4 Answers4

1

I'd use a reduce function for this:

const students = [ 
  { name: 'Romeo Minnock', semester: 12 },
  { name: 'Romeo Minnock', semester: 8 },
  { name: 'Gideon Heinemann', semester: 19 },
  { name: 'Gideon Heinemann', semester: 1 },
  { name: 'Gideon Heinemann', semester: 19 },
  { name: 'Gideon Heinemann', semester: 12 },
  { name: 'Brant Colegrove', semester: 3 },
  { name: 'Brant Colegrove', semester: 17 },
  { name: 'Gideon Heinemann', semester: 1 },
  { name: 'Gideon Heinemann', semester: 12 } 
]

students.reduce((list, current) => {
    // Check that the list does not contain this current value
    // if not push it to the array
    if (!list.find(s => s.name === current.name && s.semester === current.semester)) {
      list.push(current);
    }

    return list;
}, []);
Kousha
  • 32,871
  • 51
  • 172
  • 296
1

Here's a working solution based on this: https://stackoverflow.com/a/20339709/7919626

var sameNameStudent = [{
    name: 'Romeo Minnock',
    semester: 12
  },

  {
    name: 'Romeo Minnock',
    semester: 8
  },

  {
    name: 'Gideon Heinemann',
    semester: 19
  },

  {
    name: 'Gideon Heinemann',
    semester: 1
  },

  {
    name: 'Gideon Heinemann',
    semester: 19
  },

  {
    name: 'Gideon Heinemann',
    semester: 12
  },

  {
    name: 'Brant Colegrove',
    semester: 3
  },

  {
    name: 'Brant Colegrove',
    semester: 17
  },

  {
    name: 'Gideon Heinemann',
    semester: 1
  },

  {
    name: 'Gideon Heinemann',
    semester: 12
  }
];

function multiDimensionalUnique(arr) {
    var uniques = [];
    var itemsFound = {};
    for(var i = 0, l = arr.length; i < l; i++) {
        var stringified = JSON.stringify(arr[i]);
        if(itemsFound[stringified]) { continue; }
        uniques.push(arr[i]);
        itemsFound[stringified] = true;
    }
    return uniques;
}

console.log(multiDimensionalUnique(sameNameStudent));
Word Rearranger
  • 1,306
  • 1
  • 16
  • 25
0

It's easier to create an array without duplicates than removing the duplicates while looping the array.

Reduce the array to a Map, with a key that is built of the object's values, the spread the Map.values() iterator back to an array:

const data = [{"name":"Romeo Minnock","semester":12},{"name":"Romeo Minnock","semester":8},{"name":"Gideon Heinemann","semester":19},{"name":"Gideon Heinemann","semester":1},{"name":"Gideon Heinemann","semester":19},{"name":"Gideon Heinemann","semester":12},{"name":"Brant Colegrove","semester":3},{"name":"Brant Colegrove","semester":17},{"name":"Gideon Heinemann","semester":1},{"name":"Gideon Heinemann","semester":12}]

const result = [...
  data.reduce((m, o) => {
    const key = Object.values(o).join('--') // another option is JSON.stringify(o) if the object can have nested object values
    
    return m.has(key) ? m : m.set(key, o)
  }, new Map())
.values()]

console.log(result)
Ori Drori
  • 183,571
  • 29
  • 224
  • 209
0

The reason your algorithm does not work is because you apparently haven't looked careful enough into how splice works.

You don't pass an array element to splice, like you did -- you pass it at least the index of the first (leftmost, earliest) element where removal (and/or addition) will start, and, optionally, the number of elements to remove (or it will remove all elements starting from the index you pass as first argument). All subsequent arguments are then taken to be elements you want added, starting where removed elements were.

Since you apparently want to remove a single element -- which would be what you'd be doing if you were to eliminate duplicates like you try to do with your algorithm -- the correct expression in your case must be someNameStudent.splice(l, 1).

Your comparison predicate (the criteria you use to determine equality between elements) may also be insufficient, even when the mistake with splice is corrected -- you only compare on the value of semester property -- didn't you imply elements are only duplicate when both name and semester are equal? If that's the case, you need to have sameNameStudent[k].name == sameNameStudent[l].name && sameNameStudent[k].semester == sameNameStudent[l].semester as expression in your if statement.

Armen Michaeli
  • 8,625
  • 8
  • 58
  • 95