Javascript 在对象数组中查找最后一个匹配的对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33268863/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Find last matching object in array of objects
提问by Graeck
I have an array of objects. I need to get the object type ("shape" in this example) of the last object, remove it, and then find the index of the previous object in the array that has the same type, e.g. "shape".
我有一个对象数组。我需要获取最后一个对象的对象类型(在此示例中为“形状”),将其删除,然后在数组中找到具有相同类型的前一个对象的索引,例如“形状”。
var fruits = [
{
shape: round,
name: orange
},
{
shape: round,
name: apple
},
{
shape: oblong,
name: zucchini
},
{
shape: oblong,
name: banana
},
{
shape: round,
name: grapefruit
}
]
// What's the shape of the last fruit
var currentShape = fruits[fruits.length-1].shape;
// Remove last fruit
fruits.pop(); // grapefruit removed
// Find the index of the last round fruit
var previousInShapeType = fruits.lastIndexOf(currentShape);
// should find apple, index = 1
So, obviously the type in this example will be "round". But I'm not looking for an array value of "round". I'm looking for where fruits.shape = round.
所以,显然这个例子中的类型将是“圆形”。但我不是在寻找“圆形”的数组值。我正在寻找fruit.shape = round 的地方。
var previousInShapeType = fruits.lastIndexOf(fruits.shape = currentShape);
But just using that doesn't work. I'm sure I'm missing something simple. How do I find the last item in the array where the shape of the object = round?
但仅仅使用它是行不通的。我确定我错过了一些简单的东西。如何找到对象形状为圆形的数组中的最后一项?
采纳答案by AtheistP3ace
var previousInShapeType, index = fruits.length - 1;
for ( ; index >= 0; index--) {
if (fruits[index].shape == currentShape) {
previousInShapeType = fruits[index];
break;
}
}
You can also loop backwards through array.
您还可以通过数组向后循环。
Fiddle: http://jsfiddle.net/vonn9xhm/
回答by Luke Liu
var fruit = fruits.slice().reverse().find(fruit => fruit.shape === currentShape);
回答by Den
You can transform your array to an array boolean
type and get the last true
index.
您可以将数组转换为数组boolean
类型并获取最后一个true
索引。
const lastIndex = fruits.map(fruit =>
fruit.shape === currentShape).lastIndexOf(true);
回答by Anupam Maurya
by using lodash library
通过使用lodash 库
You can find the last logical element.
您可以找到最后一个逻辑元素。
_.findLast([1,2,3,5,4],?(n) =>?{
??return?n?%?2?==?1;
});
output: 5
输出:5
回答by evilive
plain JS:
普通JS:
var len = fruits.length, prev = false;
while(!prev && len--){
(fruits[len].shape == currentShape) && (prev = fruits[len]);
}
lodash:
洛达什:
_.findLast(fruits, 'shape', currentShape);
回答by Willem Dehaes
While the currently accepted answer will do the trick, the arrival of ES6 (ECMA2015) added the spreadoperator which makes it easy to duplicate your array (this will work fine for the fruit
array in your example but beware of nested arrays). You could also make use of the fact that the pop
method returns the removed element to make your code more concise. Hence you could achieve the desired result with the following 2 lines of code
虽然当前接受的答案可以解决问题,但 ES6 (ECMA2015) 的到来添加了扩展运算符,这使得复制数组变得容易(这对于fruit
您的示例中的数组可以正常工作,但要注意嵌套数组)。您还可以利用该pop
方法返回已删除元素的事实来使您的代码更加简洁。因此,您可以使用以下 2 行代码实现所需的结果
const currentShape = fruits.pop().shape;
const previousInShapeType = [...fruits].reverse().find(
fruit => fruit.shape === currentShape
);
回答by Jonah Williams
You should use filter! filter takes a function as an argument, and returns a new array.
你应该使用过滤器!filter 接受一个函数作为参数,并返回一个新数组。
var roundFruits = fruits.filter(function(d) {
// d is each element of the original array
return d.shape == "round";
});
Now roundFruits will contain the elements of the original array for which the function returns true. Now if you want to know the original array indexes, never fear - you can use the function map. map also operates on an array, and takes a function which acts on the array. we can chain map and filter together as follows
现在 roundFruits 将包含函数返回 true 的原始数组的元素。现在,如果您想知道原始数组索引,请不要害怕 - 您可以使用函数 map。map 还对数组进行操作,并采用一个作用于该数组的函数。我们可以将 map 和 filter 链接在一起,如下所示
var roundFruits = fruits.map(function(d, i) {
// d is each element, i is the index
d.i = i; // create index variable
return d;
}).filter(function(d) {
return d.shape == "round"
});
The resulting array will contain all objects in the original fruits array for which the shape is round, and their original index in the fruits array.
结果数组将包含原始fruits数组中形状为圆形的所有对象,以及它们在fruits数组中的原始索引。
roundFruits = [
{
shape: round,
name: orange,
i: 0
},
{
shape: round,
name: apple,
i: 1
},
{
shape: round,
name: grapefruit
i: 4
}
]
Now you can do whatever you need to with the exact knowledge of the location of the relevant data.
现在,您可以根据相关数据位置的确切知识做任何您需要做的事情。
// get last round element
fruits[4];
回答by Krit
I would suggest another nice solution which doesn't bother cloning a new object using reverse()
.
我会建议另一个不错的解决方案,它不会打扰使用reverse()
.
I use reduceRight
to does the job instead.
我reduceRight
过去常常做这项工作。
function findLastIndex(array, fn) {
if (!array) return -1;
if (!fn || typeof fn !== "function") throw `${fn} is not a function`;
return array.reduceRight((prev, currentValue, currentIndex) => {
if (prev > -1) return prev;
if (fn(currentValue, currentIndex)) return currentIndex;
return -1;
}, -1);
}
And usage
和用法
findLastIndex([1,2,3,4,5,6,7,5,4,2,1], (current, index) => current === 2); // return 9
findLastIndex([{id: 1},{id: 2},{id: 1}], (current, index) => current.id === 1); //return 2
回答by Ed I
This is a solution that does not depend on reverse
, and therefore does not require "cloning" the original collection.
这是一个不依赖于 的解决方案,reverse
因此不需要“克隆”原始集合。
const fruit = fruits.reduce((acc, fruit, index) => (
fruit.shape === currentShape ? index : acc
), 0);