JavaScript数组对象排序未按预期工作

JavaScript数组对象排序未按预期工作,javascript,arrays,sorting,object,ramda.js,Javascript,Arrays,Sorting,Object,Ramda.js,我的数组对象如下 var data = [{"weight":0,"name":"New Arrivals"},{"weight":0,"name":"Weekly Promotions"},{"weight":0,"name":"Sale"},{"weight":0,"name":"Extended Size"},{"weight":0,"name":"Accessories and Shoes"},{"weight":0,"name":"Activewear"},{"weight":0,"

我的数组对象如下

 var data = [{"weight":0,"name":"New Arrivals"},{"weight":0,"name":"Weekly Promotions"},{"weight":0,"name":"Sale"},{"weight":0,"name":"Extended Size"},{"weight":0,"name":"Accessories and Shoes"},{"weight":0,"name":"Activewear"},{"weight":0,"name":"Disney Project"},{"weight":0,"name":"Dresses and Jumpsuits"},{"weight":0,"name":"Fleece"},{"weight":0,"name":"HEATTECH Collection"},{"weight":0,"name":"Ines de la Fressange"},{"weight":0,"name":"Intimates"},{"weight":0,"name":"Jeans"},{"weight":0,"name":"Loungewear"},{"weight":0,"name":"Outerwear and Blazers"},{"weight":0,"name":"Pants"},{"weight":0,"name":"Shirts and Blouses"},{"weight":0,"name":"Skirts"},{"weight":0,"name":"Socks and Hosiery"},{"weight":0,"name":"Sweaters"},{"weight":0,"name":"Sweatshirts and Sweatpants"},{"weight":0,"name":"T-Shirts and Tops"},{"weight":0,"name":"UT: Graphic Tees"},{"weight":0,"name":"Wear To Work"},{"weight":0,"name":"Mix and Match"}]
我试图根据属性权重对其进行排序,但如果权重的所有值都为0,我需要输出上的原始顺序。但是这个功能并没有像预期的那样工作,相反,顺序正在改变

使用了ramda和JavaScript排序

var sortedData = R.sortBy(R.prop('weight'), data);

两个案例的结果如下

var output = [{"weight":0,"name":"Jeans"},{"weight":0,"name":"New Arrivals"},{"weight":0,"name":"Sale"},{"weight":0,"name":"Extended Size"},{"weight":0,"name":"Accessories and Shoes"},{"weight":0,"name":"Activewear"},{"weight":0,"name":"Disney Project"},{"weight":0,"name":"Dresses and Jumpsuits"},{"weight":0,"name":"Fleece"},{"weight":0,"name":"HEATTECH Collection"},{"weight":0,"name":"Ines de la Fressange"},{"weight":0,"name":"Intimates"},{"weight":0,"name":"Weekly Promotions"},{"weight":0,"name":"Loungewear"},{"weight":0,"name":"Outerwear and Blazers"},{"weight":0,"name":"Pants"},{"weight":0,"name":"Shirts and Blouses"},{"weight":0,"name":"Skirts"},{"weight":0,"name":"Socks and Hosiery"},{"weight":0,"name":"Sweaters"},{"weight":0,"name":"Sweatshirts and Sweatpants"},{"weight":0,"name":"T-Shirts and Tops"},{"weight":0,"name":"UT: Graphic Tees"},{"weight":0,"name":"Wear To Work"},{"weight":0,"name":"Mix and Match"}]
预期:当所有案例的权重值为0时,我预期结果与输入相同


非常感谢您的帮助。

您的问题是JavaScript中的排序不能保证稳定。ECMA-262规范规定:

此数组的元素已排序。排序不一定是稳定的(即,比较相等的元素不一定保持其原始顺序)


这个问题包括一个指向稳定排序的链接以及其他几个选项。

您的问题是JavaScript中的排序不能保证稳定。ECMA-262规范规定:

此数组的元素已排序。排序不一定是稳定的(即,比较相等的元素不一定保持其原始顺序)


这个问题包括一个指向稳定排序的链接以及其他几个选项。

最简单的解决方案是保存位置,然后在对象相等时进行比较:

var sortData = data.slice(0);

sortData.forEach(function(element, index){
    element.index = index;
});

sortData.sort(function(a,b) {
    var diff = a.weight - b.weight;
    return diff === 0 ? a.index - b.index : diff;
});

sortData.forEach(function(element){
    delete element.index;
});

最简单的解决方案是保存位置,然后在对象相等时进行比较:

var sortData = data.slice(0);

sortData.forEach(function(element, index){
    element.index = index;
});

sortData.sort(function(a,b) {
    var diff = a.weight - b.weight;
    return diff === 0 ? a.index - b.index : diff;
});

sortData.forEach(function(element){
    delete element.index;
});

您要查找的是名为
稳定性
的排序算法的属性。这意味着等值元素的顺序在排序后保持不变。不同的浏览器使用不同的排序算法,有些浏览器使用稳定算法,有些浏览器使用不稳定算法。您可以在此SO线程上看到浏览器之间的差异:


正如您在Ramda源代码中看到的,它使用内置的排序机制,因此如果使用Ramda,您会得到相同的结果:

您要查找的是名为
稳定性的排序算法的属性。这意味着等值元素的顺序在排序后保持不变。不同的浏览器使用不同的排序算法,有些浏览器使用稳定算法,有些浏览器使用不稳定算法。您可以在此SO线程上看到浏览器之间的差异:

正如您在Ramda源代码中看到的,它使用了内置的排序机制,因此如果使用Ramda,您会得到相同的结果:

A suggestion with。这里有索引,并使用第二个链式排序条件保留原始排序

mapped.sort(function (a, b) {
    return a.value - b.value || a.index - b.index;
});
//要排序的数组
var data=[{weight:0,name:“New Arrivals”},{weight:0,name:“Weekly Promotions”},{weight:0,name:“Extended Size”},{weight:0,name:“Accessories and Shoes”},{weight:0,name:“Activewear”},{weight:0,name:“Disney Project”},{weight:0,name:“连衣裙和连体衣”},{weight:0,name:“Fleece”},{weight:0,name:“Heartech Collection”},{weight:0,name:“Ines de la Fressange”},{weight:0,name:“Nemites”},{weight:0,name:“Loungewear”},{weight:0,name:“Outerwear and Blazers”},{weight:0,name:“Pants”},{weight:0,name:“Shirts”},{weight:0,name:“裙子”},{weight:0,name:“袜子和袜子”},{weight:0,name:“毛衣”},{weight:0,name:“运动衫和运动裤”},{weight:0,name:“T恤和上衣”},{weight:0,name:“UT:Graphic T恤”},{weight:0,name:“上班穿”},{weight:0,name:“混搭”};
//临时数组保存具有位置和排序值的对象
var mapped=data.map(函数(el,i){
返回{
索引:i,,
值:el.weight
};
});
//对包含缩减值的映射数组进行排序
映射.排序(函数(a,b){
返回a.value-b.value | | a.index-b.index;
});
//用于生成订单的容器
var result=mapped.map(函数(el){
返回数据[el.index];
});
console.log(结果);
.as控制台包装{max height:100%!important;top:0;}
建议。这里有索引,并使用第二个链式排序条件保留原始排序

mapped.sort(function (a, b) {
    return a.value - b.value || a.index - b.index;
});
//要排序的数组
var数据=[{weight:0,name:“New Arrivals”},{weight:0,name:“Weekly Promotions”},{weight:0,name:“Extended Size”},{weight:0,name:“Accessories and Shoes”},{weight:0,name:“Activewear”},{weight:0,name:“Disney Project”},{weight:0,name:“连衣裙和连体衣”},{weight:0,name::羊毛,{weight:0,name:“Heartech Collection”},{weight:0,name:“Ines de la Fressange”},{weight:0,name:“亲密者”},{weight:0,name:“牛仔裤”},{weight:0,name:“休闲装”},{weight:0,name:“裤子”},{weight:0,name:“衬衫和衬衫”},{weight:0,name:“裙子”},{weight:0,name:“袜子和袜子”},{weight:0,name:“毛衣”},{weight:0,name:“运动衫和运动裤”},{weight:0,name:“T恤和上衣”},{weight:0,name:“UT:Graphic T恤”},{weight:0,name:“穿着上班”},{weight:0,name:“混搭”};
//临时数组保存具有位置和排序值的对象
var mapped=data.map(函数(el,i){
返回{
索引:i,,
值:el.weight
};
});
//对包含缩减值的映射数组进行排序
映射.排序(函数(a,b){
返回a.value-b.value | | a.index-b.index;
});
//用于生成订单的容器
var result=mapped.map(函数(el){
返回数据[el.index];
});
console.log(结果);

作为控制台包装{max height:100%!important;top:0;}
您可以使用下划线的u.sortBy(数据,'weight')进行稳定排序。 哟