Javascript - 按2个属性排序对象数组

时间:2017-08-17 17:19:50

标签: javascript arrays sorting

我想用2个不同的属性对对象数组进行排序。

这些是我的对象

array = [{ resVal: "25FA15", resFlow: 49, resName: "Rendimiento Tri-Seal Completo", resPhoto: "Tri-Sealseries.png", resHP: 1.5 },
 { resVal: "25FA2", resFlow: 52, resName: "Rendimiento Tri-Seal Completo", resPhoto: "Tri-Sealseries.png", resHP: 2 },
{ resVal: "45FA2", resFlow: 53, resName: "Rendimiento Hi-Cap Completo", resPhoto: "HighCapseries.png", resHP: 2 },
{ resVal: "35FA2", resFlow: 59, resName: "Rendimiento Hi-Cap Completo", resPhoto: "HighCapseries.png", resHP: 2 }]

我想用更高的“resFlow”值对数组进行排序,但是使用最低的“resHP”值。

我想把我的数组放到这样:

array = [{ resVal: "25FA15", resFlow: 49, resName: "Rendimiento Tri-Seal Completo", resPhoto: "Tri-Sealseries.png", resHP: 1.5 },
{ resVal: "35FA2", resFlow: 59, resName: "Rendimiento Hi-Cap Completo", resPhoto: "HighCapseries.png", resHP: 2 },
{ resVal: "45FA2", resFlow: 53, resName: "Rendimiento Hi-Cap Completo", resPhoto: "HighCapseries.png", resHP: 2 },
 { resVal: "25FA2", resFlow: 52, resName: "Rendimiento Tri-Seal Completo", resPhoto: "Tri-Sealseries.png", resHP: 2 }]

希望有人可以帮助我。

谢谢。

4 个答案:

答案 0 :(得分:8)

您可以对指定的键顺序及其排序顺序使用链式方法。

数组按属性

排序
  • resHP,升序和
  • resFlow,降序。

它适用于计算delta,这反映了两个对象的关系。如果该值为零,则两个值相等,并计算并返回下一个增量。



var array = [{ resVal: "25FA15", resFlow: 49, resName: "Rendimiento Tri-Seal Completo", resPhoto: "Tri-Sealseries.png", resHP: 1.5 }, { resVal: "25FA2", resFlow: 52, resName: "Rendimiento Tri-Seal Completo", resPhoto: "Tri-Sealseries.png", resHP: 2 }, { resVal: "45FA2", resFlow: 53, resName: "Rendimiento Hi-Cap Completo", resPhoto: "HighCapseries.png", resHP: 2 }, { resVal: "35FA2", resFlow: 59, resName: "Rendimiento Hi-Cap Completo", resPhoto: "HighCapseries.png", resHP: 2 }];

array.sort(function (a, b) {
    return a.resHP - b.resHP || b.resFlow - a.resFlow;
});

console.log(array);

.as-console-wrapper { max-height: 100% !important; top: 0; }




答案 1 :(得分:0)

  

我的原始答案不正确。这是更正和扩展的答案。

基本上,要求是按resHP属性升序排序,然后对任何关系排序,按resFlow属性降序排序。

现在,Javascript的Array.prototype.sort函数允许我们对数组进行排序。它接受一个参数,即“compareFunction”。 compareFunction接受两个参数,这些参数是要比较的数组的元素,并且它必须返回它们在预期结果数组中的相对位置。

function compareFunction (itemA, itemB) {...}
     如果结果中compareFunction(a, b)之前的b

a会返回大于零的数值。

     如果结果中compareFunction(a, b)后面有b,则

a会返回小于零的数值。

     

compareFunction(a, b)返回,如果在排序数组时ab在相对顺序方面被认为是等效的。例如,在排序[5, 3, 5]时,两个5都被认为是等价的,因此当调用compareFunction(5,5)时,数组应该返回0。

对于排序字符串,不需要提供compareFunction。根据规范,当未提供compareFunction时,数组中的每个值都将转换为字符串,然后进行排序。这是一个例子:

console.log('["z", "ct", "a", "aa", "ab", "bc"].sort(): ', ["z", "ct", "a", "aa", "ab", "bc"].sort());

常见错误:

比较没有compareFunction的数字

尽管compareFunction在规范中是可选的,但如果在排序数字或其他对象时未提供它,则可能导致不正确的结果。请考虑以下示例:

console.log("[1, 2, 5, 3, 0, 20].sort(): ", [1, 2, 5, 3, 0, 20].sort());

这里20出现在3之前因为每个数字在比较之前被转换为字符串,并且因为“20”在字典中的“3”之前出现(如果有这样的字典)它在结果中出现在“3”之上。

从compareFunction返回布尔值而不是数值

这是我在原始答案中的错误。

当你从compareFunction中返回一个布尔值而不是一个数值时,布尔值将被转换为数字。含义true将变为1,false将变为0,但您不会返回-1。

var array = [
  {
    compareThis: 1,
    originalIndex: 1
  },
  {
    compareThis: 2,
    originalIndex: 2
  },
  {
    compareThis: -1,
    originalIndex: 3
  },
  {
    compareThis: -2,
    originalIndex: 4
  }
];

console.log(array.sort((a, b) => a.compareThis > b.compareThis));

这里的结果是未排序的相同数组,因为当比较2和-1时,比较2> -1返回false,转换为0.但是当compareFunction返回0时,它表示两个元素的顺序应保持不变。因此,数组不会被排序。

对此数组进行排序的正确方法是:

var array = [
  {
    compareThis: 1,
    originalIndex: 1
  },
  {
    compareThis: 2,
    originalIndex: 2
  },
  {
    compareThis: -1,
    originalIndex: 3
  },
  {
    compareThis: -2,
    originalIndex: 4
  }
];

console.log(array.sort((a, b) => a.compareThis - b.compareThis));

因此,解决问题中提出的问题的正确方法是:

var array = [{ resVal: "25FA15", resFlow: 49, resName: "Rendimiento Tri-Seal Completo", resPhoto: "Tri-Sealseries.png", resHP: 1.5 },
 { resVal: "25FA2", resFlow: 52, resName: "Rendimiento Tri-Seal Completo", resPhoto: "Tri-Sealseries.png", resHP: 2 },
{ resVal: "45FA2", resFlow: 53, resName: "Rendimiento Hi-Cap Completo", resPhoto: "HighCapseries.png", resHP: 2 },
{ resVal: "35FA2", resFlow: 59, resName: "Rendimiento Hi-Cap Completo", resPhoto: "HighCapseries.png", resHP: 2 }];


// The requirement is to sort ascending by resHP property and then for any ties, sort descending by resFlow property.
/* array.sort(function(a, b) {
  if (a.resHP > b.resHP) {
    return 1;
  } else if (a.resHP === b.resHP) {
    if (a.resFlow > b.resFlow) {
      return -1;
    } else if (a.resFlow === b.resFlow) {
      return 0;
    } else {
      return 1;
    }
  } else {
    return -1;
  }
}); */

// Simplified to the following as we are working with numbers.
array.sort(function sortByResHP(a, b) {
  return (a.resHP - b.resHP) !== 0 ? (a.resHP - b.resHP) : (b.resFlow - a.resFlow);
});

console.log("Result: ", array);

当然,这可以进一步缩短,如另一个答案所示。我将离开compareFunction的较长版本,以便于阅读。

原始(不正确)答案

您可以使用Array#sort

array = [{ resVal: "25FA15", resFlow: 49, resName: "Rendimiento Tri-Seal Completo", resPhoto: "Tri-Sealseries.png", resHP: 1.5 },
 { resVal: "25FA2", resFlow: 52, resName: "Rendimiento Tri-Seal Completo", resPhoto: "Tri-Sealseries.png", resHP: 2 },
{ resVal: "45FA2", resFlow: 53, resName: "Rendimiento Hi-Cap Completo", resPhoto: "HighCapseries.png", resHP: 2 },
{ resVal: "35FA2", resFlow: 59, resName: "Rendimiento Hi-Cap Completo", resPhoto: "HighCapseries.png", resHP: 2 }]


array.sort(function(d1,d2) {
  if(d1.resHP == d2.resHP) {
    return d1.resFlow < d2.resFlow;
  } else {
    return d1.resHP > d2.resHP;
  }
});

console.log(array);

答案 2 :(得分:0)

这是一种按多个值对对象数组进行排序的简单方法

arr.sort((a,b) => a.firstVal.localeCompare(b.firstVal) || a.secondVal.localeCompare(b.secondVal))

因此您的情况将是

array.sort((a,b) => a.resHP.localeCompare(b.resHP) || b.resFlow.localeCompare(a.resFlow)

答案 3 :(得分:0)

将此视为更通用的解决方案:

<iostream>