如何从对象数组中获取最小(最小)值?

How to get least(min) value from array of object?

我有一个包含 json 对象列表的数组,如下所述:

[
    {
        "id":1,
        "type":"type1",
        "selling_price":2199,
    },
    {
        "id":2,
        "type":"type1",
        "selling_price":4999,
    },
    {
        "id":3,
        "type":"type1",
        "selling_price":6999,
    },
    {
        "id":4,
        "type":"type2",
        "selling_price":1999,
    },
    {
        "id":5,
        "type":"type2",
        "selling_price":2399,
    },
    {
        "id":6,
        "type":"type2",
        "selling_price":2999,
    }
]

我只想提取 type="type1" 的最低售价。 type1 的最低价格应为 2199 我尝试使用以下方法但它不起作用

_.map(arr, price => {
    if(price.type=="type1") {
        let pp =_.min(price, function(minPrice){ return minPrice.selling_price; });
        console.log(pp)
    }
});

编辑@VLAZ 建议的代码

data() {
    return {
        minSellingPrice:'',
        arr:[]
    }
},
method() {
    leastPrice() {
        if(this.arr) {
            const result = _.chain(arr)
              .filter(item => item.type === "type1")
              .map('selling_price')
              .min()
              .value()
            this.minSellingPrice=result;
        }       
        else this.minSellingPrice=''
    }
}

默认情况下 this.minSellingPrice 应该是空的,但是每当 this.minSellingPrice 显示为无穷大时使用此代码。

你使用了lodash的函数minBy和过滤函数

let filter_arr = _.filter(arr, function(o) { return o.type=='type1';})
_.minBy(filter_arr,function(o) { 
  return o.selling_price; 
 });    
 

结果如下

{id: 1, selling_price: 2199, type: "type1"}

希望对您有所帮助

你映射错了。您在回调中有一个条件,它一次只给您一个项目。相反,你应该 filter() the collection to only the type you want first, then get the min() price.

Underscore 具有 _.chain() method 允许您在同一数据集上执行多个操作而无需保存中间结果。要在最后获得结果,您需要调用 .value() 以表示不会链接进一步的调用:

const arr = [ { "id":1, "type":"type1", "selling_price":2199, }, { "id":2, "type":"type1", "selling_price":4999, }, { "id":3, "type":"type1", "selling_price":6999, }, { "id":4, "type":"type2", "selling_price":1999, }, { "id":5, "type":"type2", "selling_price":2399, }, { "id":6, "type":"type2", "selling_price":2999, } ];

const result = _.chain(arr)
  .filter(item => item.type === "type1")
  .min('selling_price')
  .value();
  
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.11.0/underscore-min.js"></script>

如果您只想要价格,而不是对象本身,您可以使用 map() 来提取 属性:

const arr = [ { "id":1, "type":"type1", "selling_price":2199, }, { "id":2, "type":"type1", "selling_price":4999, }, { "id":3, "type":"type1", "selling_price":6999, }, { "id":4, "type":"type2", "selling_price":1999, }, { "id":5, "type":"type2", "selling_price":2399, }, { "id":6, "type":"type2", "selling_price":2999, } ];

const result = _.chain(arr)
  .filter(item => item.type === "type1")
  .map('selling_price')
  .min()
  .value();
  
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.11.0/underscore-min.js"></script>

如果您想要在空数组的情况下使用回退值,目前代码将 return Infinity,因为这是 min 的默认值 return。不幸的是,Underscore 没有足够全面的 API 来轻松解决它。例如,一种简单的方法是只检查该值并将其替换为另一个值。

if (result === Infinity) {
    result = null;
}

如果您只想使用 Undescore,另一种方法是通过 mixin() 定义您自己的方法。许多方法可能会解决这里的问题,但作为一般的辅助方法,我会选择 or() ,它允许您将一个值与另一个值交换:

/**
 * Generic function that either value or if the value fails a test a fallback
 * @param {*} value - value to be tested or substituted
 * @param {*} otherValue - fallback in case `value` fails the test
 * @param {Function} [test] - what the value would be tested against. By default it fails for null or undefined
 */
_.mixin({
  or: function(value, otherValue, test = x => x != null ) {
    return test(value) ? value : otherValue ;
  }
});

const fullArray = [ { "id":1, "type":"type1", "selling_price":2199, }, { "id":2, "type":"type1", "selling_price":4999, }, { "id":3, "type":"type1", "selling_price":6999, }, { "id":4, "type":"type2", "selling_price":1999, }, { "id":5, "type":"type2", "selling_price":2399, }, { "id":6, "type":"type2", "selling_price":2999, } ];

const emptyArray = [];


function getMinimum(arr) {
  return _.chain(arr)
    .filter(item => item.type === "type1")
    .map('selling_price')
    .min()
    .or("", _.isFinite) //use the or() mixin and pass a different test function that rejects `Infinity`
    .value();
}
  
const fullResult = getMinimum(fullArray);
const emptyResult = getMinimum(emptyArray);

console.log(`fullResult is [${fullResult}]`);
console.log(`emptyResult is [${emptyResult}]`); //empty string
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.11.0/underscore-min.js"></script>

最后,如果您喜欢 Underscore 但发现 API 有点局限,就像在这种情况下,我建议切换到 Lodash。它 非常 接近 Undescore,因为它在过去的某个时候分裂了。 Lodash 具有更一致的界面和更多的功能,因此在很多情况下它是 Underscore 的直接升级或至少是同等水平。你想要在 Lodash 中表达的功能是这样的:

const fullArray = [ { "id":1, "type":"type1", "selling_price":2199, }, { "id":2, "type":"type1", "selling_price":4999, }, { "id":3, "type":"type1", "selling_price":6999, }, { "id":4, "type":"type2", "selling_price":1999, }, { "id":5, "type":"type2", "selling_price":2399, }, { "id":6, "type":"type2", "selling_price":2999, } ];

const emptyArray = [];


function getMinimum(arr) {
  return _.chain(arr) //no need for .chain() as Lodash implicitly chains via this
  .filter(item => item.type === "type1")
  .map('selling_price')
  .min() //min defaults to `undefined` if nothing is found
  .defaultTo(''); // similar to the `or()` mixin above but only for `undefined`, `null`, or `NaN`
  .value()
}
  
const fullResult = getMinimum(fullArray);
const emptyResult = getMinimum(emptyArray);

console.log(`fullResult is [${fullResult}]`);
console.log(`emptyResult is [${emptyResult}]`); //empty string
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js"></script>

与 Underscore 不同,Lodash 开箱即用地支持完成整个操作所需的一切。