Hala Ba
Hala Ba

Reputation: 249

Javascript, remove property from one of two similar objects in array

Let's assume we have this data set:

var array = [
                {

                        "name": "a",
                        "group": "a"
                },
                {
                        "name": "a",
                        "group": "a"
                },{
                        "name": "b",
                        "group": "b"
                },
                {
                        "name": "b",
                        "group": "b"
                },
                {
                        "name": "c"
                }
            ];

and I want to loop through the array to see if there are two objects have the same group value, then remove the second of them.

for(var i = 0 ; i<array.length;i++){
                var a = array[i];
                for(var j = 0; j< array.length;j++){
                    if(array[j].group == a.group){
                        var b = array[j];
                        // I need code here to remove property "group" from the variable b only
                        break;
                    }
                }
            }

the final results I want are:

var array2 = [
                {
                    "name": "a",
                    "group": "a"
                },
                {
                    "name": "a"
                },{
                    "name": "b",
                    "group": "b"
                },
                {
                    "name": "b"
                },{
                    "name":"c"
                }                    
            ];

NOTE: I tried delete array[j].group but it caused to remove both group property from both equal objects. How can I solve that?

Upvotes: 0

Views: 191

Answers (6)

Arnauld
Arnauld

Reputation: 6110

You don't need imbricated loops to do this. You can use .forEach() while keeping track of the groups that have been encountered so far. This can be done by using either the optional thisArg parameter or an explicit variable.

For instance:

var array = [
  { "name": "a", "group": "a" },
  { "name": "a", "group": "a" },
  { "name": "b", "group": "b" },
  { "name": "b", "group": "b" },
  { "name": "c" }
];

var grp = {};

array.forEach(function(o) {
  grp[o.group] ? delete o.group : grp[o.group] = true;
});

console.log(array);

Upvotes: 0

Aleksey L.
Aleksey L.

Reputation: 37918

You shouldn't compare same items, just shift indexes in inner loop:

 var array = [{"name": "a", "group": "a"},
             {"name": "a", "group": "a"},
             {"name": "b", "group": "b"},
             {"name": "b", "group": "b"},
             {"name": "c"}];


for(var i = 0 ; i < array.length - 1; i++){
  var a = array[i];
  if(!a.group){
    continue;
  }

  for(var j = i+1; j < array.length; j++){
    var b = array[j];
    if(b.group === a.group){
      delete b.group;
    }
  }
}

console.log(array)

Upvotes: 2

rpadovani
rpadovani

Reputation: 7360

I'd go with a different approach:

Little explanation of the if condition:

array.slice(0, i): we take only the previous elements of the array.

.filter(v => v.group === val.group) we see if they have the same value for property group.

.length === 0) If there is at least one element with the same value of group, we do not enter the if and return only the name, otherwise we return the value itself

var array = [{"name": "a", "group": "a"},
             {"name": "a", "group": "a"},
             {"name": "b", "group": "b"},
             {"name": "b", "group": "b"},
             {"name": "c"}];

array = array.map((val, i) => {
  if (array.slice(0, i).filter(v => v.group === val.group).length === 0) {
    return val;
  }
  return {name: val.name};
})

console.log(array)

Upvotes: 1

vbuhlev
vbuhlev

Reputation: 509

Here is a simple code which might help:

var groups = {};
array.forEach(function(o) {
  if (groups[o.group]) {
    delete o.group;
  } else {
    groups[o.group] = true;
  }
})

You can also use more functional approach but you will need an additional utility library or have to implement some of the methods yourself.

var groups = array.map(function(o) { return o.group; }).unique();

groups
  .map(function(group) {
    return array.filter(function(o) { o.group == group }).slice(1);
  })
  .flatten()
  .forEach(function(o) { delete o.group });

flatten & unique are not included in the JavaScript spec.

Upvotes: 0

nioKi
nioKi

Reputation: 1289

Just store all the group values you already have seen, and remove them if you see them again. Moreover, this will save you a loop.

var myArray = [...];

var existingGroups = [];

myArray.forEach(function(item){
    if(item.group){
        if(existingGroups.indexOf(item.group) === -1)
            existingGroups.push(item.group);
    else
        delete item.group;
    }
});

Upvotes: 1

You can try this:

var tmpObj = {};
tmpObj.name = array[j].name;
array.splice(j, 1, tmpObj);

It should remove the element with index j and add new object with only name.

Upvotes: 1

Related Questions