【问题标题】:Getting the array index for an item based on one of its properties根据项目的一个属性获取项目的数组索引
【发布时间】:2015-11-15 15:07:56
【问题描述】:

给定一个对象数组,我正在尝试编写一个方法,该方法可以获取某个项的索引,其中特定属性的值在数组中已出现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

我更喜欢格式良好的下划线/lodash 解决方案,而不是 20 多行纯 JS 解决方案。如果你能用纯 JS 做更少的事情,那很好。

我已经尝试使用 _.groupBy 和 _.pluck 来获取各个列表,但找不到将这些信息从原始数组转换回索引的方法。

【问题讨论】:

  • nthItem 应该从1 开始?或者可以是0?
  • nthItem 应该从1 开始,但它返回的索引应该从0 开始。

标签: javascript arrays underscore.js lodash


【解决方案1】:

我不确定你在哪里得到 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);

【讨论】:

    【解决方案2】:

    如果foods 数组没有改变,一个更简单的解决方案可能是创建一个从所有者到数组索引的哈希图并进行哈希图查找。

    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
    

    【讨论】:

      【解决方案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;
      }
      

      【讨论】:

      • 不错!顺便说一句,您将noOFTimes 放在底部。
      【解决方案4】:

      这是一个简单的 lodash 解决方案:

      function getIndex(owner, nthItem) {
          return _.indexOf(foods,
              _.filter(foods, { owner: owner })[nthItem - 1]);
      }
      

      第一步是使用filter() 来获取具有正确owner 的对象。然后,只需使用nthItem 在过滤结果中查找对象即可。如果存在,我们使用indexOf() 来返回foods 中第n 个项目的索引。如果不存在任何项目,则返回 -1。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-10-18
        • 2011-11-29
        • 2021-05-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-29
        相关资源
        最近更新 更多