Найти последний индекс элемента внутри массива по определенному условию
Скажем, у меня есть массив объектов:
[{'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];