Reputation: 249
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
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
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
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
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
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
Reputation: 3091
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