Найти последний индекс элемента внутри массива по определенному условию

Скажем, у меня есть массив объектов:

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

Какой самый чистый способ получить последний индекс элемента, где a имеет значение "что-то". В этом случае 3. Есть ли способ избежать циклов...

Ответ 1

Вы можете использовать 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')

Ответ 2

Вот многократно используемая версия машинописи, которая отражает сигнатуру функции 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;
}

Ответ 3

Вы можете выполнить итерацию с конца и выйти из цикла, если он найден.

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);

Ответ 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})

Ответ 5

Пожалуйста, взгляните на этот метод.

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);

Ответ 6

вот что я использовал, чтобы получить последний активный элемент:

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

Ответ 7

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

Во-первых, это не массив объектов, а массив массивов. Массив объектов будет выглядеть так:

[{'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;
    }
}

Ответ 9

Интересно, почему многие люди хотели бы всегда избегать циклов в наши дни. Они являются такими же естественными структурами, как if и чистой последовательностью кодовых строк. Чтобы не повторять себя, напишите для него функцию, что вы даже можете добавить в 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);

Ответ 10

Вы можете использовать reverse и map вместе, чтобы предотвратить изменение исходного массива.

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;
}

Ответ 11

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) 

Ответ 12

Вы можете использовать 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")

Ответ 13

почему бы просто не получить длину и не использовать в качестве указателя массива, например.

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

то получите последний индекс массива, получив длину массива и минус '1', так как индекс массива всегда начинается с '0'

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