Javascript 按两个最近的字段对js数组排序

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

我想按两个字段对数组进行排序,同时提供所需的数字进行排序。我尝试使用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},
  {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。谢谢,这实际上是最简单的解决方案!很高兴它有帮助:)你能提供一个用例吗?