Javascript 自然排序、对象数组、多列、反转等
我迫切需要实现客户端排序,通过我们的tastypieapi模拟排序,它可以获取多个字段并返回排序数据。例如,如果我有如下数据:Javascript 自然排序、对象数组、多列、反转等,javascript,sorting,underscore.js,lodash,ramda.js,Javascript,Sorting,Underscore.js,Lodash,Ramda.js,我迫切需要实现客户端排序,通过我们的tastypieapi模拟排序,它可以获取多个字段并返回排序数据。例如,如果我有如下数据: arr = [ { name: 'Foo LLC', budget: 3500, number_of_reqs: 1040 }, { name: '22nd Amendment', budget: 1500, number_of_reqs: 2000 }, { name: 'STS 10', budget: 50000,
arr = [
{ name: 'Foo LLC', budget: 3500, number_of_reqs: 1040 },
{ name: '22nd Amendment', budget: 1500, number_of_reqs: 2000 },
{ name: 'STS 10', budget: 50000, number_of_reqs: 500 },
...
etc.
]
和给定的要排序的列,例如:['name','-number\u of_reqs']
它应该按名称
(升序)和数量
(降序)排序。我想不起来了,
首先,它必须是“自然排序”,如果我们谈论的是对单个列进行排序,那么它应该很容易获得,但我需要能够对多个列进行排序
另外,我也不清楚为什么在使用lodash的\uuu.sortBy
时会得到不同的结果(从api的工作方式来看)?\uuu.sortBy
不是“自然的”还是我们的api坏了
我也在寻找一个优雅的解决方案。最近刚开始使用,真是太棒了。我打赌这会更容易建立排序我需要使用它?我已经试过了,但还是做不好。帮个小忙
upd:
我发现它并与Ramda一起使用,如下所示:
fn = R.compose(R.sort(naturalSort), R.pluck("name"))
fn(arr)
var on = R.curry(function(map, cmp) {
return R.useWith(cmp, map, map);
return R.useWith(cmp, [map, map]); // since Ramda >0.18
});
var props = ["-budget", "name"];
var comparator = Ru.compareProps(props);
var sortedList = R.sort(comparator, arr);
似乎适用于平面数组,但我仍然需要找到一种方法将其应用于数组中的多个字段使用javascript本机排序:
Array.prototype.multisort=函数(列){
var arr=此;
arr.sort(函数(a,b){
返回比较(a、b、0);
});
函数比较(a、b、colindex){
if(colindex>=columns.length)返回0;
var columnname=列[colindex];
变量a_field1=a[columnname];
var b_field1=b[columnname];
var asc=(共索引%2==0);
如果(a_字段1b_字段1)返回asc?1:-1;
否则返回比较(a、b、colindex+1);
}
}
var arr=[{name:'Foo LLC',预算:3500,需求数量:1040},
{名称:'22修正案',预算:1500,需求数量:2000},
{名称:'STS 10',预算:50000,需求数量:5000},
{名称:'STS 10',预算:50000,需求数量:500}];
arr.multisort(['name','number'u of_reqs');
if(window.console)window.console.log(arr)代码>我认为这是可行的
var-arr=[
{名称:'Foo LLC',预算:3500,需求数量:1040},
{名称:'22修正案',预算:1500,需求数量:2000},
{名称:'STS 10',预算:50000,需求数量:5000},
{名称:'STS 10',预算:50000,需求数量:500}
];
变量列=[“名称”,“需求数量];
变量组数=/(?\d*\。?\d+)/g;
var naturalSort=函数(a、b、columnname){
变量a_field1=a[columnname],
b_field1=b[columnname],
aa=字符串(a_字段1)。拆分(数量_组),
bb=字符串(b_字段1)。拆分(组数),
最小=数学最小值(aa.长度,bb.长度);
对于(变量i=0;iy),则返回1;
}
返回0;
};
arr.sort(函数(a,b){
var结果;
对于(var i=0;i
看起来很有效
真的吗?我希望返回已排序的名称数组,而不是按名称属性对对象数组进行排序
不幸的是,使用sortBy
无法提供自定义的比较函数(自然排序所需),将多个列组合在一个值中进行一致比较可能是可行的,但很麻烦
我仍然不知道如何对多个字段执行此操作
函数式编程在这里可以做很多事情,不幸的是Ramda并没有真正为比较器配备有用的函数(除了)。我们还需要三名助手:
on
(如),它采用a->b
转换和b->b->Number
比较器函数在两个a
s上生成比较器。我们可以用Ramda创建它,如下所示:
fn = R.compose(R.sort(naturalSort), R.pluck("name"))
fn(arr)
var on = R.curry(function(map, cmp) {
return R.useWith(cmp, map, map);
return R.useWith(cmp, [map, map]); // since Ramda >0.18
});
var props = ["-budget", "name"];
var comparator = Ru.compareProps(props);
var sortedList = R.sort(comparator, arr);
求反
-一种对比较进行求反的函数:
function negate(cmp) {
return R.compose(R.multiply(-1), cmp);
}
Bergi的答案很有用,也很有趣,但它改变了您所请求的API。下面是一个创建您正在寻找的API的示例:
var multisort = (function() {
var propLt = R.curry(function(name, a, b) {
return a[name] < b[name];
});
return function(keys, objs) {
if (arguments.length === 0) {throw new TypeError('cannot sort on nothing');}
var fns = R.map(function(key) {
return key.charAt(0) === "-" ?
R.pipe(R.comparator(propLt(R.substringFrom(1, key))), R.multiply(-1)) :
R.comparator(propLt(key));
}, keys);
var sorter = function(a, b) {
return R.reduce(function(acc, fn) {return acc || fn(a, b);}, 0, fns);
}
return arguments.length === 1 ? R.sort(sorter) : R.sort(sorter, objs);
};
}());
multisort(['name', '-number_of_reqs'], arr); //=> sorted clone
var multisort=(函数(){
var propLt=R.curry(函数名,a,b){
返回a[name]分类克隆
它是手动curry而不是调用R.curry
,因为创建单独的排序函数需要相当多的工作,如果使用同一组键对多个列表进行排序,则可以重用这些函数。如果这不是一个问题,这可以简化一点。如果您愿意为您的项目添加另一个依赖项,则会提供一个compareProps函数,它完全满足原始问题的要求
因此,根据您最初的示例,按照预算和名称进行降序排序,您可以执行以下操作:
fn = R.compose(R.sort(naturalSort), R.pluck("name"))
fn(arr)
var on = R.curry(function(map, cmp) {
return R.useWith(cmp, map, map);
return R.useWith(cmp, [map, map]); // since Ramda >0.18
});
var props = ["-budget", "name"];
var comparator = Ru.compareProps(props);
var sortedList = R.sort(comparator, arr);
升序,降序呢?升序返回结果,-降序返回结果。您还可以在compare方法中使用一个标志并否定降序的输出。这是javascript中最自然的输出。B