根据项目的一个属性获取项目的数组索引
Getting the array index for an item based on one of its properties
给定一个对象数组,我正在尝试编写一个方法来获取项目的索引,其中特定 属性 具有在数组中出现 n
次的值.
这段代码可能更容易描述我想要实现的目标:
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
我更喜欢格式正确的 underscore/lodash 解决方案,而不是 20 多行的纯 JS 解决方案。如果您可以使用纯 JS 以 less 的方式完成,那很好。
我已经用 _.groupBy 和 _.pluck 尝试了一些东西来取出单独的列表,但找不到将该信息转换回原始数组的索引的方法。
我不确定你从哪里得到 20 多行 js,但你需要最简单的 for
循环:
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);
另一种变体,具有 map
和 filter
功能
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);
下面的 getIndex
函数应该可以解决您的问题,如果没有找到 getIndex 函数的预期输出,它会返回 -1
。
function getIndex(owner, nthItem){
var noOfTimes = 1;
for(var i = 0; i < foods.length && noOfTimes <= nthItem; i++) {
if(foods[i].owner == owner) noOfTimes++;
}
//returns -1 if it did not find the expected output.
return i >= foods.length || noOfTimes < nthItem ? -1 : i - 1;
}
如果 foods
数组没有改变,一个更简单的解决方案可能是创建一个从所有者到数组索引的 hashmap 并进行 hashmap 查找。
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
这是一个简单的 lodash 解决方案:
function getIndex(owner, nthItem) {
return _.indexOf(foods,
_.filter(foods, { owner: owner })[nthItem - 1]);
}
第一步是使用filter() to get the objects that have the correct owner
. Then, it's just a matter of using nthItem
to find the object in the filtered result. If it exists, we use indexOf()到returnfoods
中第n项的索引。 Returns -1
如果没有项目存在。
给定一个对象数组,我正在尝试编写一个方法来获取项目的索引,其中特定 属性 具有在数组中出现 n
次的值.
这段代码可能更容易描述我想要实现的目标:
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
我更喜欢格式正确的 underscore/lodash 解决方案,而不是 20 多行的纯 JS 解决方案。如果您可以使用纯 JS 以 less 的方式完成,那很好。
我已经用 _.groupBy 和 _.pluck 尝试了一些东西来取出单独的列表,但找不到将该信息转换回原始数组的索引的方法。
我不确定你从哪里得到 20 多行 js,但你需要最简单的 for
循环:
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);
另一种变体,具有 map
和 filter
功能
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);
下面的 getIndex
函数应该可以解决您的问题,如果没有找到 getIndex 函数的预期输出,它会返回 -1
。
function getIndex(owner, nthItem){
var noOfTimes = 1;
for(var i = 0; i < foods.length && noOfTimes <= nthItem; i++) {
if(foods[i].owner == owner) noOfTimes++;
}
//returns -1 if it did not find the expected output.
return i >= foods.length || noOfTimes < nthItem ? -1 : i - 1;
}
如果 foods
数组没有改变,一个更简单的解决方案可能是创建一个从所有者到数组索引的 hashmap 并进行 hashmap 查找。
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
这是一个简单的 lodash 解决方案:
function getIndex(owner, nthItem) {
return _.indexOf(foods,
_.filter(foods, { owner: owner })[nthItem - 1]);
}
第一步是使用filter() to get the objects that have the correct owner
. Then, it's just a matter of using nthItem
to find the object in the filtered result. If it exists, we use indexOf()到returnfoods
中第n项的索引。 Returns -1
如果没有项目存在。