Javascript 按两个最近的字段对js数组排序
我想按两个字段对数组进行排序,同时提供所需的数字进行排序。我尝试使用lodash,但没有达到预期效果 比如说Javascript 按两个最近的字段对js数组排序,javascript,sorting,lodash,Javascript,Sorting,Lodash,我想按两个字段对数组进行排序,同时提供所需的数字进行排序。我尝试使用lodash,但没有达到预期效果 比如说 const data = [ {name: 'first', score: 22, average: 59}, {name: 'second', score: 34, average: 83}, {name: 'third', score: 40, average: 24}, {name: 'fourth', score: 29, average: 49}, {nam
const data = [
{name: 'first', score: 22, average: 59},
{name: 'second', score: 34, average: 83},
{name: 'third', score: 40, average: 24},
{name: 'fourth', score: 29, average: 49},
{name: 'fifth', score: 23, average: 55}
];
// call function like this
sortByTwoFields({field:'score', number:21}, {field:'average', number:50});
预期的结果是
const result = [
{name: 'fifth', score: 23, average: 55},
{name: 'fourth', score: 29, average: 49},
{name: 'first', score: 22, average: 59},
{name: 'third', score: 40, average: 24},
{name: 'second', score: 34, average: 83}
];
如果您有任何想法,我们将不胜感激。您所期望的结果似乎略有偏差,因为
第四个
的总差值为9,而第一个
的总差值为10。下面的函数的调用类似于sortByTwoFields(data,{field:'score',number:21},{field:'average',number:50})
。如果要对对象进行优先级排序,可以向该对象添加weight
属性,否则默认为1
function sortByTwoFields (data, info1, info2) {
if (! ("weight" in info1)) {
info1.weight = 1;
}
if (! ("weight" in info2)) {
info2.weight = 1;
}
return data.sort(function (a, b) {
var adiff1 = a[info1.field] - info1.number;
var adiff2 = a[info2.field] - info2.number;
var bdiff1 = b[info1.field] - info1.number;
var bdiff2 = b[info2.field] - info2.number;
return Math.abs(adiff1) * info1.weight + Math.abs(adiff2) * info2.weight - Math.abs(bdiff1) * info1.weight - Math.abs(bdiff2) * info2.weight;
});
}
我不相信你的预期结果是正确的,因为第四个的总差异较小 无论如何,该函数将计算出给定值和数字之间的总差值,然后根据该差值进行排序
function sortByTwoFields(数据、字段1、字段2){
数据排序(函数(a,b){
//算出两个字段的差值,然后将它们相加,得到总数
var totalDifferenceA=Math.abs(field1.number-a[field1.field])+Math.abs(field2.number-a[field2.field]);
var totalDifferenceB=Math.abs(field1.number-b[field1.field])+Math.abs(field2.number-b[field2.field]);
//如果a的总数较小,那么b应该排在第一位
返回totalDifferenceA-totalDifferenceB;
});
}
常数数据=[
{姓名:'第一',分数:22,平均数:59},
{姓名:'第二',分数:34,平均数:83},
{姓名:'第三',分数:40,平均数:24},
{姓名:'第四',分数:29,平均数:49},
{姓名:'fifth',分数:23,平均值:55}
];
sortByTwoFields(数据,{field:'score',number:21},{field:'average',number:50});
控制台日志(数据)代码>简单地使用的怎么样
排序(数据,[a=>Math.abs(a.score-21),a=>Math.abs(a.average-50)])
这还不够吗
编辑
嗯,是的!如果您需要从一个位置进行排序(执行),并且只需要(正好是2个)2个嵌套字段,那么这个ole线性函数是可以的,但是如果您从多个位置调用,并且使用具有最接近值的diff字段(嵌套),那么您可以将其包装在一个函数中,动态准备iTree并将其传递给sortBy
以下是一个工作示例:
var数据=[
{姓名:'第一',分数:22,平均数:59},
{姓名:'第二',分数:34,平均数:83},
{姓名:'第二',分数:34,平均值:80},
{姓名:'第三',分数:40,平均数:24},
{姓名:'第四',分数:29,平均数:49},
{姓名:'fifth',分数:23,平均值:55}
];
函数排序环(arr,…字段){
//这将创建回调数组,类似于第一个示例中的用户
让iteratees=fields.map(f=>o=>Math.abs(f.number-o[f.field]);
返回u.sortBy(arr,iteratees);
}
//为“arr”参数和所有其他参数传递数据
//字段数组参数的排序键/最近值
var res=sortByClosest(数据,{field:'score',number:21},{field:'average',number:50});
控制台日志(res)代码>
您可以通过按任意数量的字段(而不仅仅是两个字段)排序,轻松地使其成为通用字段:
function sortByFields(objs, fields) {
const diffToFields = obj =>
_(fields).map(f => Math.abs(obj[f] - f.number)).sum();
return _(objs).sortBy(diffToFields).value();
}
const sortedData = sortByFields(data, [
{field: 'score', number: 21},
{field: 'average', number: 50},
]);
为什么要发送数字?您所说的“按数字排序”是什么意思?您期望的结果是什么样的?我想按与我发送的数字最接近的结果对它们进行排序。请给出运行此函数后您期望的确切数组。您是否对第一个字段进行了优先级排序?您提供了错误的预期结果。名为fourth
的项目应位于名为first
的项目之前,因为名为fourth
的项目的距离等于9,名为first
的项目的距离等于10。谢谢,这实际上是最简单的解决方案!很高兴它有帮助:)你能提供一个用例吗?