Reputation: 6131
I have an array of objects, like this:
var data = [
{
name: "block",
sameid: 500,
parentid: 62
},
{
name: "circle",
sameid: 500,
parentid: 62
},
{
name: "cube",
sameid: 500,
parentid: 62
}
]
I need to make a filter on that array to remove objects that have sameid and same parentid. But here is a twist that bothers me... If I get this array of objects:
var data = [
{
name: "block",
sameid: 500,
parentid: 62
},
{
name: "circle",
sameid: 500,
parentid: 62
},
{
name: "cube",
sameid: 500,
parentid: 62
},
{
name: "grain",
sameid: 500,
parentid: 63
}
]
You can see that object with name grain (last one), it has different parentid. if that is the case, then nothing should be removed.
I am breaking my head around this one. First criteria that I must take into account is a sameid. I should group them by it. Then somehow check for parent ids.
The array can contain many different sameid's and parentid's
UPDATE: In the first case, where the data has three objects. All should be removed, becouse all of them have same sameid and parentid.
In the second case, where the data has four objects all four should be preserved, since there is one different object with different parentid.
UPDATE Desired result:
var filteredObjects = [];
data = [
{
name: "block",
sameid: 500,
parentid: 62
},
{
name: "circle",
sameid: 500,
parentid: 62
},
{
name: "cube",
sameid: 500,
parentid: 62
},
{
name: "grain",
sameid: 500,
parentid: 63
}
]
In this case, filteredObject will have all values, since there is one different parentid:
filteredObjects [{
name: "block",
sameid: 500,
parentid: 62
},
{
name: "circle",
sameid: 500,
parentid: 62
},
{
name: "cube",
sameid: 500,
parentid: 62
},
{
name: "grain",
sameid: 500,
parentid: 63
}]
In this case:
var filteredObjects = [];
data = [
{
name: "block",
sameid: 500,
parentid: 62
},
{
name: "circle",
sameid: 500,
parentid: 62
},
{
name: "cube",
sameid: 500,
parentid: 62
}
]
filteredObject will have no values. The data array can contain different sameid as well.
Upvotes: 1
Views: 113
Reputation: 386578
You could build a tree with sameid
and parentid
. Then filter the items and return only the one who have two or more parenid
.
function filter(array) {
var hash = {};
array.forEach(function (a) {
hash[a.sameid] = hash[a.sameid] || {};
hash[a.sameid][a.parentid] = true;
});
return array.filter(function (a) {
return Object.keys(hash[a.sameid]).length > 1;
});
}
var data0 = [{ name: "block", sameid: 500, parentid: 62 }],
data1 = [{ name: "block", sameid: 500, parentid: 62 }, { name: "circle", sameid: 500, parentid: 62 }, { name: "cube", sameid: 500, parentid: 62 }],
data2 = [{ name: "block", sameid: 500, parentid: 62 }, { name: "circle", sameid: 500, parentid: 62 }, { name: "cube", sameid: 500, parentid: 62 }, { name: "grain", sameid: 500, parentid: 63 }],
data3 = [{ name: "block", sameid: 500, parentid: 62 }, { name: "circle", sameid: 500, parentid: 62 }, { name: "cube", sameid: 500, parentid: 62 }, { name: "grain", sameid: 500, parentid: 63 }, { name: "library", sameid: 600, parentid: 66 }, { name: "wood", sameid: 600, parentid: 66 }, { name: "water", sameid: 700, parentid: 77 }, { name: "fire", sameid: 700, parentid: 78 }, { name: "orphan", sameid: 300, parentid: 12 }];
console.log(filter(data0));
console.log(filter(data1));
console.log(filter(data2));
console.log(filter(data3));
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 3
Reputation: 1322
You may also look into this approach:
data.reduce(function(p, c, index){
if (p.length !== index) return [];
if (p.length === 0) {
return p.concat(c);
}
else if (p[0].sameid === c.sameid && p[0].parentid === c.parentid){
return p.concat(c);
}
return [];
}, []);
Upvotes: 0
Reputation: 460
i have tried to solve your question , you need to add underscorejs for the following code.
var data2 = [
{
name: "block",
sameid: 500,
parentid: 62
},
{
name: "circle",
sameid: 500,
parentid: 62
},
{
name: "cube",
sameid: 500,
parentid: 62
},
{
name: "grain",
sameid: 500,
parentid: 63
}
]
var backup = data2;
var count1 = 0;
var count2 = 0;
for(var i = 0; i< data2.length ;i ++){
for(var j = i+1;j<data2.length ;j++){
if(data2[i].sameid == data2[j].sameid && data2[i].parentid == data2[j].parentid){
count1++;
}
else if((data2[i].sameid == data2[j].sameid && data2[i].parentid != data2[j].parentid) ||(data2[i].sameid != data2[j].sameid && data2[i].parentid == data2[j].parentid) ){
count2++;
}
}
if(count2 == 0 && count1 != 0){
backup = _.reject(backup,function(d){return d.sameid == data2[i].sameid && d.parentid == data2[i].parentid })
}
count2=0;count1=0;
}
console.log(backup,"my new array")
Upvotes: 0
Reputation: 944
you can try this
var distincts = []
for (var i = 0; i < data.length; i++)
if (distincts.indexOf(data[i].sameid)==-1)
distincts.push(data[i].sameid);
if(distincts.length==1){
var distinctp = []
for (var i = 0; i < data.length; i++)
if (distinctp.indexOf(data[i].sameid)==-1)
distinctp.push(data[i].sameid);
if(distincts.length==1){
data.splice(0,data.length)
}
}
Upvotes: 0
Reputation: 34189
You can simply iterate through your initial array and build a new one while checking the uniqueness.
It can be done by utilizing Array.prototype.filter
:
var data = [
{
name: "same sameid and parentid",
sameid: 500,
parentid: 62
},
{
name: "same sameid and parentid",
sameid: 500,
parentid: 62
},
{
name: "different sameid, same parentid",
sameid: 501,
parentid: 62
},
,
{
name: "same sameid, different parentid",
sameid: 500,
parentid: 63
}
];
var set = {};
var newData = data.filter(function(x) {
var key = x.sameid + "_" + x.parentid;
if (set[key])
return false;
return (set[key] = true);
});
console.log(newData);
Note that this algorithm takes every first occurence of same IDs. You can implement another logics, if you need.
Upvotes: 2
Reputation: 174957
You can use ES2015's Set
structure to find out whether or not you have more than one kind:
const parentIdSet = new Set(data.map(item => item.parentid));
console.log(parentIdSet.size);
// If 1, you only have one parentId in the entire dataset.
A Set is a collection of unique values. By putting all of the parent IDs into a Set, all of the duplicate values are removed, and you have only unique values left. If the size of the Set is 1, it means that you only have one parentid in the entire dataset.
Using a set means you can avoid having to store the initial values somewhere and try to compare. The Set does it for you automatically, and with better performance (probably)
Upvotes: 2