【问题标题】:Find the lastIndexOf() an object with a key in array of objects使用对象数组中的键查找 lastIndexOf() 对象
【发布时间】:2018-03-04 04:29:30
【问题描述】:

我正在寻找一种方法来从数组中的某个点查找 Javascript 中对象的最后一个索引。例如:

array.lastIndexOf(object.key, start);

到目前为止,我还没有找到解决这个问题的好方法。我可以从“开始”点拼接数组,反转它,然后在切片数组中搜索键值,但这对我来说似乎是一个低效的解决方案。

编辑:

为了更详细地说明问题,我发布了我最终用来解决问题的代码。本质上;我所做的是使用 While 循环遍历数组中的先前值。

getLastValue = (index) => {
  const arr = [
    {'d':'01-02-2017','v':'123'},
    {'d':'02-02-2017'},
    {'d':'04-02-2017'},
    {'d':'05-02-2017','v':'456'},
    ...
  ];

  let lastValue;

  while (arr[index] && !arr[index].v) {
    index--;
  }

  lastValue = arr[index];

  return lastValue;
}

【问题讨论】:

  • 这是一个数组,对吧?你正在寻找最后一个实例?一个简单的for(x = array.length - 1; x >= start; x--) {if (array[x] == object.key) return x; } 不起作用有什么原因吗? ** 请注意,我的数学很糟糕,所以可能是x > start
  • lastIndexOf 到底有什么不好的地方?
  • @Bergi 它处理原始类型,而不是对象,请参阅我提出的解决方案

标签: javascript arrays object ecmascript-6 lastindexof


【解决方案1】:

我使用了示例代码,如下所示:

//find last index in object array
const lastIndexOf = arr.reduce((acc,cur,idx)=>cur.key==xxx?idx:acc,-1)

//find last index of object in object array
const lastIndexOfObject = arr.reduce((acc,cur,idx)=>cur.key==xxx?cur:acc,undefined)

【讨论】:

    【解决方案2】:

    就个人而言,我不会选择任何一种解决方案。原因如下:

    LastIndexOf:

    问题在于在搜索数组时比较元素。它确实使用严格相等来比较元素。因此,比较对象总是会失败,除非它们是相同的。在 OP 情况下,它们是不同的。

    切片和反转单行@adeneo

    给定一个包含三个元素[{key: A},{key: B},{key: C}] 的数组,查找key = D 的最后一个索引将为您提供3 的索引。这是错误的,因为最后一个索引应该是 -1(未找到)

    遍历数组

    虽然这不一定是错误的,但遍历整个数组以查找元素并不是最简洁的方法。它很有效yes,但可读性会受到影响。如果让我选一个,我可能会选这个。如果可读性/简单性是您的朋友,那么下面是另一种解决方案。


    一个简单的解决方案

    我们可以使lastIndexOf 工作,我们只需要使值具有可比性(严格相等符合)。或者简单地说:我们需要将对象映射到我们想要找到使用 javascript 原生实现的最后一个索引的单个属性。

    const arr = [ { key: "a" }, { key: "b" }, { key: "c" }, { key: "e" }, { key: "e" }, { key: "f" } ];
    
    arr.map(el => el.key).lastIndexOf("e"); //4
    arr.map(el => el.key).lastIndexOf("d"); //-1
    
    // Better:
    const arrKeys = arr.map(el => el.key);
    arrKeys.lastIndexOf("c"); //2
    arrKeys.lastIndexOf("b"); //1
    

    快速解决方案

    简单的向后查找(尽可能简洁和快速)。注意 -1 返回而不是 null/undefined。

    const arr = [ { key: "a" }, { key: "b" }, { key: "c" }, { key: "e" }, { key: "e" }, { key: "f" } ];
    
    const lastIndexOf = (array, key) => {
      for(let i = array.length - 1; i >= 0; i--){
        if(array[i].key === key)
          return i;
      }
      return -1;
    };
    
    lastIndexOf(arr, "e"); //4
    lastIndexOf(arr, "x"); //-1
    

    【讨论】:

    • 为什么要在这个循环中递减常量变量?这在javascript中是否允许?
    • 我不知道 codepen 是否无法正常工作,或者您对此不正确:codepen.io/BT101/pen/wvWJWxO?editors=0010
    • 嗯。你说的对。我错了。我将它与 for..in 循环和其他语言的行为混淆了。 medium.com/@mautayro/…我已经调整了我的答案。感谢您指出。我还删除了我的评论,以免造成任何混乱。我想我正在用 i-- 改变变量
    【解决方案3】:

    你可以这样做:

    1. 反转你的数组:let newArr = arr.reverse()
    2. 使用findIndex:newArr.findIndex(obj => obj.d == "your String")

    【讨论】:

      【解决方案4】:

      使用 ES2015 和 findIndex,您可以传递回调来查找对象键。

      如果您复制数组并将其反转,您可以通过从总长度中减去该索引来找到最后一个(和 1,因为数组是从零开始的)

      这不是很有效,但它是一行,并且适用于正常大小的数组,即不是一百万个索引

      var idx = arr.length - 1 - arr.slice().reverse().findIndex( (o) => o.key == 'key' );
      

      var arr = [{key : 'not'}, {key : 'not'}, {key : 'key'}, {key : 'not'}];
      
      var idx = arr.length - 1 - arr.slice().reverse().findIndex( (o) => o.key == 'key' ); // 2
      
      console.log(idx)

      一种更有效的方法是向后迭代,直到找到要查找的对象,然后打破循环

      var arr = [{key: 'not'}, {key: 'not'}, {key: 'key'}, {key: 'not'}];
      
      var idx = (function(key, i) {
        for (i; i--;) {
          if (Object.values(arr[i]).indexOf(key) !== -1) {
            return i;
            break;
          }
        }   return -1;
      })('key', arr.length);
      
      console.log(idx)

      【讨论】:

      • 这是一个很好的解决方案。我最终使用了您扩展方法的修改版本。我将修改原始问题以显示我的问题的更完整版本,以及我如何修改您的 for 循环方法。感谢您的帮助!
      • 当没有找到密钥而不是预期的-1时,您的单行返回array.length
      【解决方案5】:

      我想你想要类似下面的东西:

      var arr = [ { key: "a" }, { key: "b" }, { key: "c" }, { key: "e" }, { key: "e" }, { key: "f" } ];
      
      console.log(lastIndexOf("e", 2));
      
      function lastIndexOf(keyValue, start) {
          for (var i = arr.length - 1; i >= start; i--) {
              if (arr[i].key === keyValue) {
                  return i;
              }
          }
          return null;
      }

      【讨论】:

      • 嘿;谢谢法利。你是对的;正是我需要的。我在上面的问题块中发布了我的完整解决方案。很遗憾;我必须将答案提供给显然在您之前几秒钟做出响应的用户。不过,我感谢您的帮助。
      【解决方案6】:

      只需尝试在整个海量中找到最后一个索引并比较它即可开始

      let ind = array.lastIndexOf(object.key); 
      if (ind > start) {return}
      

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-13
      相关资源
      最近更新 更多