我需要通过属性price
订购对象数组。
现在,我可以执行以下操作:
function orderByPriceASC(a,b) {
return(
a.price < b.price ? -1
: a.price > b.price ? 1
: 0
);
}
function orderByPriceDESC(a,b) {
return(
a.price < b.price ? 1
: a.price > b.price ? -1
: 0
);
}
function sortByPrice(order) {
setProductList((prevState) => {
const aux = Array.from(prevState);
order === 'asc' ? aux.sort(orderByPriceASC) : aux.sort(orderByPriceDESC);
return aux;
});
}
但是有没有办法构造这种结构,这样我就可以获得一个适用于ASC和DESC顺序的比较函数?
类似的东西:
function orderByPrice(a,b,order) {
return(
a.price < b.price ?
order === 'asc' ? -1 : 1
: a.price > b.price ? 1
order === 'asc' ? 1 : -1
: 0
);
}
问题是我必须将多余的参数发送到Array.sort
方法中,我认为这是不可能的。也许有一些包装功能。
如何实现?
答案 0 :(得分:1)
您可以定义函数并通过绑定并发送自定义参数(如
)将其传递给排序
let arr = [{price: 1},{price: 11},{price: 7},{price: 1},{price: 9},{price: 5},]
function orderByPrice(order, a,b) {
if(a.price < b.price) {
if(order === 'asc') {
return -1;
}
return 1;
} else if(a.price > b.price){
if(order === 'asc') {
return 1;
}
return -1
}
return 0;
}
console.log(arr.sort(orderByPrice.bind(this, 'asc')))
console.log(arr.sort(orderByPrice.bind(this, 'desc')))
答案 1 :(得分:1)
您可以使用multiplier
并根据1
变量将其设置为-1
或order
。然后将其乘以compareFunction
内部的现有表达式(这里假设price
的类型为number
)
let arr = [{ price: 2 },{ price: 1 },{ price: 3 }]
function sort(array, order) {
const multiplier = order === "asc" ? 1 : -1;
return array.sort((a, b) => multiplier * (a.price - b.price))
}
console.log(sort(arr, "asc"))
console.log(sort(arr, "desc"))
答案 2 :(得分:0)
您必须让函数返回一个接受方向作为参数的函数,然后将其传递给内部函数。我不喜欢动态类型语言中的标志,但它可能是这样的:
window
然后将实现
function sortByPrice(direction) { // either 'ASC' or 'DESC
return function (a, b) {
if (direction === 'DESC') {
const temp = a;
a = b
b = temp;
}
return (
a.price < b.price ? -1
: a.price > b.price ? 1
: 0
);
}
}
答案 3 :(得分:0)
您可以这样做:
function flip(f) {
return function (a, b) {
return f(b, a);
};
}
function orderByPriceASC(a,b) {
return (
a.price < b.price ? -1 :
a.price > b.price ? 1 :
0
);
}
function sortByPrice(order) {
setProductList((prevState) => {
const aux = Array.from(prevState);
aux.sort(order === 'asc' ? orderByPriceASC : flip(orderByPriceASC));
return aux;
});
}
这样,您不需要单独的orderByPriceDESC
函数,也不必添加任何额外的参数。
答案 4 :(得分:0)
您可以使用Array.sort和Array.slice做这样的事情:
let arr = [{ price: 2 },{ price: 1 },{ price: 3 }]
let sortBy = (arr, prop, dir=null) =>
arr.slice().sort((a,b) => (a[prop] - b[prop]) * (dir ? -1 : 1))
console.log(sortBy(arr, 'price'))
console.log(sortBy(arr, 'price', 'desc')) // <-- any truthy value for `desc`
您必须使用Array.slice来克隆数组,因为Array.sort确实会使数组发生突变,并且您需要pure
函数。来自documentation:
已排序的数组。请注意,数组是按顺序排序的,没有副本 制成。
此外,如果您正在使用lodash,那么已经有一个_.orderBy函数,它还可以对多个道具等进行排序:
let arr = [{ price: 2 },{ price: 1 },{ price: 3 }]
console.log(_.orderBy(arr, 'price'))
console.log(_.orderBy(arr, 'price', 'desc'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
答案 5 :(得分:-1)
尝试
function orderByPrice(a, b, order) {
return order === 'desc'
? a && b && b.price - a.price
: a && b && a.price - b.price
}
const b = [
{ price: 4},
{ price: 5},
{ price: 6}
]
function orderByPrice(a, b, order) {
return order === 'desc'
? a && b && b.price - a.price
: a && b && a.price - b.price
}
console.log(b.sort((a, b) => orderByPrice(a, b, 'desc')))