按特定条件查找数组内元素的最后一个索引

时间:2016-12-02 09:54:17

标签: javascript arrays

假设我有一个对象数组:

[{'a': 'something', 'b':12},
{'a': 'something', 'b':12},
{'a': 'somethingElse', 'b':12},
{'a': 'something', 'b':12},
{'a': 'somethingElse', 'b':12}]

最简洁的方法是获取元素的最后一个索引,其中a的值为'something'。在这种情况下3.有没有办法避免循环...

19 个答案:

答案 0 :(得分:18)

您可以使用findIndex获取索引。这将为您提供第一个索引,因此您必须反转该数组。

var d = [{'a': "something", 'b':12}, {'a': "something", 'b':12}, {'a': "somethingElse", 'b':12}, {'a': "something", 'b':12}, {'a': "somethingElse", 'b':12}]

function findLastIndex(array, searchKey, searchValue) {
  var index = array.slice().reverse().findIndex(x => x[searchKey] === searchValue);
  var count = array.length - 1
  var finalIndex = index >= 0 ? count - index : index;
  console.log(finalIndex)
  return finalIndex;
}

findLastIndex(d, 'a', 'something')
findLastIndex(d, 'a', 'nothing')

答案 1 :(得分:5)

如果找到,你可以从最后进行迭代并退出循环。

var data = [{ a: 'something', b: 12 }, { a: 'something', b: 12 }, { a: 'somethingElse', b: 12 }, { a: 'something', b: 12 }, { a: 'somethingElse', b: 12 }],
    l = data.length;

while (l--) {
    if (data[l].a ==='something') {
        break;
    }
}

console.log(l);

答案 2 :(得分:4)

let newArray = yourArray.filter((each)=>{
    return (each.a === something)
});
newArray[newArray.length-1];

您也可以

let reversedArray = yourArray.reverse();
reversedArray.find((each)=>{return each.a === something})

答案 3 :(得分:3)

这是一个可重用的打字稿版本,它反映了ES2015 findIndex函数的签名:

/**
* Returns the index of the last element in the array where predicate is true, and -1
* otherwise.
* @param array The source array to search in
* @param predicate find calls predicate once for each element of the array, in descending
* order, until it finds one where predicate returns true. If such an element is found,
* findLastIndex immediately returns that element index. Otherwise, findLastIndex returns -1.
*/
export function findLastIndex<T>(array: Array<T>, predicate: (value: T, index: number, obj: T[]) => boolean): number {
    let l = array.length;
    while (l--) {
        if (predicate(array[l], l, array))
            return l;
    }
    return -1;
}

答案 4 :(得分:2)

请看一下这种方法。

&#13;
&#13;
var array=[{a: 'something', b:12},
           {a: 'something', b:12},
           {a: 'somethingElse', b:12},
           {a: 'something', b:12},
           {a: 'somethingElse', b:12}
          ];

console.log(array.filter(function(item){
		return item.a=='something';
}).length);
&#13;
&#13;
&#13;

答案 5 :(得分:2)

这里是我用来获取最后一个活动元素的地方:

return this._scenarios.reverse().find(x => x.isActive);

答案 6 :(得分:2)

对我来说,反转数组听起来并不那么简单,因此我针对类似情况的解决方案是使用map()lastIndexOf()

var lastIndex = elements.map(e => e.a).lastIndexOf('something');

更新。:this answer的伪造帖子使map(cond).lastIndexOf(true)变得更好

答案 7 :(得分:1)

var arr = [
   {'a': 'something', 'b':12},
   {'a': 'something', 'b':12},
   {'a': 'somethingElse', 'b':12},
   {'a': 'something', 'b':12},
   {'a': 'somethingElse', 'b':12}
];

var item_count = 0;
var traverse_count = 0;
var last_item_traverse_count = 0;    
arr = arr.reverse();

arr.filter(function(element) {
   traverse_count += 1;
   if(item_count < 1 && element.a == 'something') {
       last_item_traverse_count = traverse_count;
       item_count += 1;
       return true;
   }

   return false;
});

var item_last_index = arr.length - last_item_traverse_count;

console.log(item_last_index);

我希望这段代码绝对有用。代码可能不遵循命名约定。对不起,我很抱歉。您可以根据需要命名这些变量。

答案 8 :(得分:1)

ES6中的类似情况如何?

  arr.indexOf(arr.filter(item => item.a === 'something').pop())

答案 9 :(得分:1)

我发现的最干净的方法是使用单个reduce。无需反转数组或使用多个循环

const items = [
  {'a': 'something', 'b': 12},
  {'a': 'something', 'b': 12},
  {'a': 'somethingElse', 'b': 12},
  {'a': 'something', 'b': 12},
  {'a': 'somethingElse', 'b': 12}
];

function findLastIndex(items, callback) {
  return items.reduce((acc, curr, index) => callback(curr) ? index : acc, 0);
}

console.log(findLastIndex(items, (curr) => curr.a === "something"));

答案 10 :(得分:0)

我想知道为什么现在很多人都想总是避免循环。它们与if s和纯代码行序列一样,都是自然结构。为避免重复自己,请为其编写一个函数,甚至可以添加到Array.prototype。以下是一个简单的例子,未经测试,只是为了这个想法。

获取索引

Array.prototype.lastIndex = function(cond) {
  if (!this.length) return -1;
  if (!cond) return this.length-1;

  for (var i=this.length-1; i>=0; --i) {
    if (cond(this[i])) return i;
  }

  return -1;
}

或直接用于元素

Array.prototype.lastOrDefault = function(cond, defaultValue) {
  if (!this.length) return defaultValue;
  if (!cond) return this[this.length-1];

  for (var i=this.length-1; i>=0; --i) {
    if (cond(this[i])) return this[i];
  }

  return defaultValue;
}

用法示例:

myArr = [1,2,3,4,5];
var ind1 = myArr.lastIndex(function(e) { return e < 3; }); 
var num2 = myArr.lastOrDefault(function(e) { return e < 3; });
var num8 = myArr.lastOrDefault(function(e) { return e > 6; }, /* explicit default */ 8);

答案 11 :(得分:0)

为什么不只是得到长度并用作数组指针,例如

var arr = [ 'test1', 'test2', 'test3' ];

然后通过获取数组的长度并减去&#39; 1&#39;来获取数组的最后一个索引。因为数组索引总是从&#39; 0&#39;

开始
var last arrIndex = arr[arr.length - 1];

答案 12 :(得分:0)

首先,这不是一个对象数组,而是一个数组数组。对象数组如下所示:

[{'a': something, 'b':12},
{'a': something, 'b':12},
{'a': somethingElse, 'b':12},
{'a': something, 'b':12},
{'a': somethingElse, 'b':12}]

通常,使用非数字索引时使用对象语法是一种很好的做法。

其次,要回答你的问题,你可以使用反向循环:

for(let i=(arr.length - 1); i>=0; i--){
    if(arr[i].a === "something"){
        index = i;
        break;
    }
}

答案 13 :(得分:0)

您可以同时使用反向和映射,以防止对原始数组进行变异。

var arr = [{'a': 'something', 'b':12},
{'a': 'something', 'b':12},
{'a': 'somethingElse', 'b':12},
{'a': 'something', 'b':12},
{'a': 'somethingElse', 'b':12}];

var index = arr.length - 1 - arr.map(x => x)
   .reverse()
   .findIndex(x => (x.a === 'something'))
if (index === arr.length) {
  index = -1;
}

答案 14 :(得分:0)

const arrSome = [{'a': 'something', 'b':12},
    {'a': 'something', 'b':12},
    {'a': 'somethingElse', 'b':12},
    {'a': 'something', 'b':12},
    {'a': 'somethingElse', 'b':12}]

const lastIndex = arrSome.reverse().findIndex(el=> el.a == 'something');//?
let index;
if (~lastIndex) {
    index =arrSome.length - lastIndex;
} else {
    index = -1
}

console.log(index) 

答案 15 :(得分:0)

您可以使用Lodash:

import findLastIndex from "lodash/findLastIndex"

const data = [
  { a: 'something', b: 12 },
  { a: 'something', b: 12 },
  { a: 'somethingElse', b: 12 },
  { a: 'something', b: 12 },
  { a: 'somethingElse', b: 12 },
]

const lastIndex = findLastIndex(data, v => v.a === "something")

答案 16 :(得分:0)

您可以使用 Math.max 通过 Array.prototype.map()

应用于符合您条件的阵列

像这个例子

private findLastIndex() {
    const filter = this.myArray.map((t, index) => {
      if (
        // your condition
      ) {
        return index;
      } else {
        return -1;
      }
    });

    return Math.max.apply(null, filter);
  }

答案 17 :(得分:0)

这是不使用(手动)循环且不更改调用数组的解决方案:

const arr = [
  {'a': 'something', 'b': 12},
  {'a': 'something', 'b': 12},
  {'a': 'somethingElse', 'b': 12},
  {'a': 'something', 'b': 12},
  {'a': 'somethingElse', 'b': 12}
];

function findLastIndex(arr, callback, thisArg) {
  return (arr.length - 1) - // Need to subtract found, backwards index from length
    arr.reduce((acc, cur) => [cur, ...acc], []) // Get reversed array
    .findIndex(callback, thisArg); // Find element satisfying callback in rev. array
}

console.log(findLastIndex(arr, (e) => e.a === "something"));

参考:

应注意,此处使用的减速器是arr.slice().reverse()的{​​{3}},如vastly outperformed中使用的。

答案 18 :(得分:0)

这是我使用的:

const lastIndex = items.filter(el => el.a === "something").length - 1