Reputation:
I have an array of JS Objects:
var a = [{a:"a1",b:"b",c:"c",prop:false},
{a:"a1",b:"b",c:"c",prop:false},
{a:"a",b:"b",c:"c",prop:false},
{a:"a2",b:"b",c:"c",prop:false},
{a:"a3",b:"b",c:"c",prop:false},
{a:"a1",b:"b",c:"c",prop:false}];
I must find duplicates of the last element but WITHOUT considering the key prop
: when I find them, the related prop boolean must be set to true
.
I did the simplest thing in the world and it works fine but I was wandering if there is something JS can do (without 3rd party libraries), better either in "elegance", modernity or performance:
var toTest = a[a.length-1];
for(var i=0;i<a.length;i++){
if(toTest.a==a[i].a && toTest.b==a[i].b && toTest.c==a[i].c){
a[i].prop = true;
a[a.length-1].prop = true;
}
}
Any tip is appreciated
Upvotes: 4
Views: 455
Reputation: 272
You can use the normal forEach
Loop
var a = [{a:"a1",b:"b",c:"c",prop:false}, {a:"a1",b:"b",c:"c",prop:false}, {a:"a",b:"b",c:"c",prop:false}, {a:"a2",b:"b",c:"c",prop:false},{a:"a1",b:"b",c:"c",prop:false},{a:"a1",b:"b",c:"c",prop:false}];
var toTest = a[a.length-1];
a.forEach(function(item){
item.prop = (item.a == toTest.a && item.b == toTest.b && item.c == toTest.c) ? true : false;
});
console.log(a);
Upvotes: 1
Reputation: 4094
Use Array.filter()
with a function that compares only a
, b
and c
.
Edit: I completely replaced my previous answer. I think Array.filter() is the way to go to search for duplicates of the last entry in the array as asked for.
Upvotes: 1
Reputation: 1074295
What you have is pretty much it. There are tweaks you can make, but it's fine as is except you want to stop one step earlier, when i < a.length - 1
(since you don't want to compare the last entry to itself and set prop
incorrectly).
Some tweaks you could do:
a[a.length-1].prop = true;
could be toTest.prop = true;
a[i]
to a variable rather than looking it up each timea
, b
, and c
instead of looking them up on the object every time (but the JavaScript engine will do that if it matters anyway)a
, b
, and c
So for instance:
// Caching the last item
var last = a[a.length - 1];
// Caching the values to check
var checka = last.a, checkb = last.b, checkc = last.c;
// Stop at i < a.length - 1, caching that to l
for (var i = 0, l = a.length - 1; i < l; ++i) {
// Cache a[i]
var entry = a[i];
if (entry.a == checka && entry.b == checkb && entry.c == checkc) {
entry.prop = last.prop = true;
}
}
Live Copy:
var a = [{a:"a1",b:"b",c:"c",prop:false},
{a:"a1",b:"b",c:"c",prop:false},
{a:"a",b:"b",c:"c",prop:false},
{a:"a2",b:"b",c:"c",prop:false},
{a:"a3",b:"b",c:"c",prop:false},
{a:"a1",b:"b",c:"c",prop:false}];
// Caching the last item
var last = a[a.length - 1];
// Caching the values to check
var checka = last.a, checkb = last.b, checkc = last.c;
// Stop at i < a.length - 1, caching that to l
for (var i = 0, l = a.length - 1; i < l; ++i) {
// Cache a[i]
var entry = a[i];
if (entry.a == checka && entry.b == checkb && entry.c == checkc) {
entry.prop = last.prop = true;
}
}
console.log(a);
.as-console-wrapper {
max-height: 100% !important;
}
Here's an ES2015+ version, just for reference:
const last = a[a.length - 1];
const {a: checka, b: checkb, c: checkc} = last;
for (let i = 0, l = a.length - 1; i < l; ++i) {
const {a: thisa, b: thisb, c: thisc} = a[i];
if (thisa == checka && thisb == checkb && thisc == checkc) {
a[i].prop = last.prop = true;
}
}
Live Copy:
const a = [{a:"a1",b:"b",c:"c",prop:false},
{a:"a1",b:"b",c:"c",prop:false},
{a:"a",b:"b",c:"c",prop:false},
{a:"a2",b:"b",c:"c",prop:false},
{a:"a3",b:"b",c:"c",prop:false},
{a:"a1",b:"b",c:"c",prop:false}];
const last = a[a.length - 1];
const {a: checka, b: checkb, c: checkc} = last;
for (let i = 0, l = a.length - 1; i < l; ++i) {
const {a: thisa, b: thisb, c: thisc} = a[i];
if (thisa == checka && thisb == checkb && thisc == checkc) {
a[i].prop = last.prop = true;
}
}
console.log(a);
.as-console-wrapper {
max-height: 100% !important;
}
Whether that meets any of your criteria is up to you.
Upvotes: 1
Reputation: 24915
You can use a combination of Array.forEach
and Array.every
. Create a list of keys to test and in every iteration, check for these keys and update object.
a[a.length-1].prop = true
looks unnecessary to me as you are not removing the item, so it will be updated in the last iteration.
var a = [{a:"a1",b:"b",c:"c",prop:false},
{a:"a1",b:"b",c:"c",prop:false},
{a:"a",b:"b",c:"c",prop:false},
{a:"a2",b:"b",c:"c",prop:false},
{a:"a3",b:"b",c:"c",prop:false},
{a:"a1",b:"b",c:"c",prop:false}];
var toTest = a[a.length -1];
var keysToTest = ['a', 'b', 'c'];
a.forEach((o)=>{
var valid = keysToTest.every((k) => o[k] === toTest[k]);
if(valid){
o.prop = true;
}
});
console.log(a)
Upvotes: 1