Given an array of objects, I'm trying to write a method that can get the index of a item where a specific property has a value that has occurred n
times in the array.
What I'm trying to achieve is probably easier described by this code:
var foods = [
{
name: "orange",
owner: "bob"
},
{
name: "carrot",
owner: "fred"
},
{
name: "apple",
owner: "bob"
},
{
name: "onion",
owner: "fred"
},
{
name: "banana",
owner: "bob"
},
{
name: "pear",
owner: "bob"
}
];
function getIndex(owner, nthItem){
// solution code
}
getIndex("bob", 3); // should return 4 as it is the index of bob's 3rd item in foods
I'd prefer a well-formed underscore/lodash solution as opposed to a 20+ line-long pure JS one. If you can do it in less with pure JS then that's fine ofc.
I've tried some stuff with _.groupBy and _.pluck to get the individual lists out, but can't find a way to translate that information back into an index from the original array.
I not sure where you get 20+ lines in js, but you need simplest for
loop:
var foods = [
{
name: "orange",
owner: "bob"
},
{
name: "carrot",
owner: "fred"
},
{
name: "apple",
owner: "bob"
},
{
name: "onion",
owner: "fred"
},
{
name: "banana",
owner: "bob"
},
{
name: "pear",
owner: "bob"
}
];
function getIndex(owner, nthItem) {
var cur = 0;
for (var i = 0; i < foods.length; i++) {
if (foods[i].owner == owner) {
if (cur + 1 == nthItem) return i;
cur += 1;
}
}
return -1;
}
document.body.innerHTML = getIndex("bob", 3);
Yet another variant, with map
and filter
functions
var foods = [{
name: "orange",
owner: "bob"
}, {
name: "carrot",
owner: "fred"
}, {
name: "apple",
owner: "bob"
}, {
name: "onion",
owner: "fred"
}, {
name: "banana",
owner: "bob"
}, {
name: "pear",
owner: "bob"
}];
function getIndex(owner, nthItem) {
var item = foods.map(function(el, index) {
return {
el: el,
index: index
};
})
.filter(function(el) {
return el.el.owner == owner;
})[nthItem-1];
return item? item.index : -1;
}
document.body.innerHTML = getIndex("bob", 3);
If the foods
array does not change, a simpler solution may be to create a hashmap from owner to array index and do a hashmap lookup.
var foods = [
{
name: "orange",
owner: "bob"
},
{
name: "carrot",
owner: "fred"
},
{
name: "apple",
owner: "bob"
},
{
name: "onion",
owner: "fred"
},
{
name: "banana",
owner: "bob"
},
{
name: "pear",
owner: "bob"
}
];
var hashmap = foods.reduce(
function (prev, curr, i, arr) {
if (curr.owner in prev)
prev[curr.owner].push(i);
else
prev[curr.owner] = [i];
return prev;
}, {}); // hashmap contains { bob: [ 0, 2, 4, 5 ], fred: [ 1, 3 ] }
function getIndex(owner, nthItem){
return hashmap[owner][nthItem - 1];
}
getIndex("bob", 3); // returns 4
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With