0

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?

3
  • I tried delete array[j].group but it caused to remove both group property from both equal objects. because at some point a === b. check the way you loop. Commented Aug 9, 2016 at 10:13
  • yes, I noticed that thanx @Thomas Commented Aug 9, 2016 at 10:35
  • And instead of deleting the property you'd better set it to null or undefined or "" whatever you want. JS-engines like Objects with the same signature; actually it's the same hidden class, but changing the signature of an Object implies also changing it's hidden class. Commented Aug 9, 2016 at 11:15

6 Answers 6

2

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)

Sign up to request clarification or add additional context in comments.

1 Comment

It doesn't work if there is more than two objects with the same group property
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.

Comments

1

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;
    }
});

Comments

1

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)

1 Comment

same notice, If there are many properties other than only name .. It would be little difficult ? I mean this way? @rpadovani
0

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.

Comments

0

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);

2 Comments

But if there are many properties other than only name .. It would be little difficult ? I mean this way?
@HalaElBarchah You are correct. Please see my updated answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.