在对象数组中查找最后匹配的对象

时间:2015-10-21 20:42:38

标签: javascript arrays

我有一个对象数组。我需要获取最后一个对象的对象类型(在此示例中为“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

所以,显然这个例子中的类型将是“圆形”。但我不是在寻找“圆”的数组值。我正在寻找fruits.shape = round的地方。

var previousInShapeType = fruits.lastIndexOf(fruits.shape = currentShape);

但只是使用它不起作用。我确定我错过了一些简单的事情。如何在数组中找到对象形状=圆形的最后一项?

11 个答案:

答案 0 :(得分:14)

var fruit = fruits.slice().reverse().find(fruit => fruit.shape === currentShape);

答案 1 :(得分:5)

您可以将数组转换为数组boolean类型并获取最后一个true索引。

const lastIndex = fruits.map(fruit => 
  fruit.shape === currentShape).lastIndexOf(true);

答案 2 :(得分:4)

var previousInShapeType, index = fruits.length - 1;
for ( ; index >= 0; index--) {
    if (fruits[index].shape == currentShape) {
        previousInShapeType = fruits[index];
        break;
    }
}

您也可以向后循环遍历数组。

小提琴:http://jsfiddle.net/vonn9xhm/

答案 3 :(得分:3)

更简单且相对有效的解决方案。 过滤并弹出!

过滤所有符合当前形状的水果,然后弹出最后一个。

fruits.filter(({shape}) => shape === currentShape).pop()

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


alert(fruits.filter(({shape}) => shape === currentShape).pop().name);

答案 4 :(得分:1)

普通JS:

{% url 'register:LoginPage' %}

lodash:

var len = fruits.length, prev = false;
while(!prev && len--){
    (fruits[len].shape == currentShape) && (prev = fruits[len]);
}

答案 5 :(得分:1)

使用 lodash库

您可以找到最后一个逻辑元素。

_.findLast([1,2,3,5,4], (n) => {
  return n % 2 == 1;
});

输出:5

答案 6 :(得分:1)

我会建议另一个不错的解决方案,它不麻烦使用reverse()克隆新对象。

我用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);
}

和用法

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

答案 7 :(得分:0)

你应该使用过滤器! filter将函数作为参数,并返回一个新数组。

var roundFruits = fruits.filter(function(d) {
 // d is each element of the original array
 return d.shape == "round";
});

现在,roundFruits将包含函数返回true的原始数组的元素。现在,如果您想了解原始数组索引,请不要担心 - 您可以使用函数映射。 map也在一个数组上运行,并采用一个作用于数组的函数。我们可以如下链接地图和过滤器

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

结果数组将包含原始fruits数组中形状为圆形的所有对象,以及它们在fruits数组中的原始索引。

roundFruits = [
{ 
    shape: round,
    name: orange,
    i: 0
},
{ 
    shape: round,
    name: apple,
    i: 1
},
{ 
    shape: round,
    name: grapefruit
    i: 4
}
]

现在,您可以根据相关数据位置的确切知识做任何您需要的事情。

// get last round element
fruits[4];

答案 8 :(得分:0)

这是一个打字稿版本:

/**
 * Returns the value of the last element in the array where predicate is true, and undefined
 * otherwise. It's similar to the native find method, but searches in descending order.
 * @param list the 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, find
 * immediately returns that element value. Otherwise, find returns undefined.
 */
export function findLast<T>(
  list: Array<T>,
  predicate: (value: T, index: number, obj: T[]) => unknown
): T | undefined {
  for (let index = list.length - 1; index >= 0; index--) {
    let currentValue = list[index];
    let predicateResult = predicate(currentValue, index, list);
    if (predicateResult) {
      return currentValue;
    }
  }
  return undefined;
}

用法:

const r = findLast([12, 43, 5436, 44, 4], v => v < 45);
console.log(r); // 4

答案 9 :(得分:0)

基于 Luke Liu's answer,但使用 ES6 的 spread operator 使其更易于阅读:

c = (a.x+a.y+a.z)*(b.x+b.y+b.z)     // multiplication of 2 expresions
c = (a.x*b.x)+(a.x*b.y)+(a.x*b.z)   // expanded
   +(a.y*b.x)+(a.y*b.y)+(a.y*b.z)
   +(a.z*b.x)+(a.z*b.y)+(a.z*b.z)
c = (a.x*b.x)                       // ordered desc by magnitude (x>=y>=z)
   +(a.x*b.y)+(a.y*b.x)
   +(a.x*b.z)+(a.z*b.x)+(a.y*b.y)
   +(a.y*b.z)+(a.z*b.y)
   +(a.z*b.z)

答案 10 :(得分:-1)

这是一种不依赖于const fruit = fruits.reduce((acc, fruit, index) => ( fruit.shape === currentShape ? index : acc ), 0); 的解决方案,因此不需要“克隆”原始集合。

<!-- first form -->
  <form  method="post" action="test.php">
    <input type="text" placeholder="Amount" name="amount">
  </form>


  <form method="post" action="test.php">
    <input  type="submit" name="submit" value="Submit" >
  </form>

<?php
  if(isset($_POST['submit'])){
    if(!empty($_POST['amount'])){
      echo $_POST['amount'];
    }else{
      echo 'empty';
    }
  }
  ?>