如何从对象数组中获取最小(最小)值?
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 开箱即用地支持完成整个操作所需的一切。
我有一个包含 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 开箱即用地支持完成整个操作所需的一切。