【问题标题】:Sorting an object with null properties yields different results between Firefox and Chrome对具有空属性的对象进行排序会在 Firefox 和 Chrome 之间产生不同的结果
【发布时间】:2020-11-11 19:31:57
【问题描述】:

我有一个对象数组,我尝试对其应用 2 种排序。对“name”属性进行简单的字母排序,然后对“rank”属性进行排序,该属性可以是数字或空值。具有 null 'rank' 的对象应排序到最终数组的末尾。

此代码在 Chrome、Safari 和 Edge 中按预期工作。然而,在 Firefox 中,它会颠倒所有具有 null 'rank' 的对象的字母顺序。

JSFiddle:https://jsfiddle.net/6Lfu1z39/

代码:

const data = [
    {
    "name": "F",
    "rank": 2
    },{
    "name": "B",
    "rank": null
    },{
    "name": "A",
    "rank": 1
    },{
    "name": "E",
    "rank": null
    },{
    "name": "D",
    "rank": null
    },{
    "name": "C",
    "rank": 2
    }
]

const nameSort = (a, b) => {
    const nameA = a.name.toUpperCase();
    const nameB = b.name.toUpperCase();

    if (nameA < nameB) {
        return -1;
    } else if (nameA > nameB) {
        return 1;
    }
    return 0;
};

const rankSort = (a, b) => {
    if (a.rank === null) {
        return 1;
    } else if (b.rank === null) {
        return -1;
    }
    return 0;
}

console.log('name only', data.sort(nameSort));
console.log('name and rank', data.sort(nameSort).sort(rankSort));

这里哪个浏览器是正确的?或者,可以做些什么来使浏览器之间保持一致?

【问题讨论】:

    标签: javascript arrays sorting firefox


    【解决方案1】:

    看起来,您为相同的比较值返回了错误的值。

    例如使用a.rank === null b.rank === null,您返回1,但在这种情况下正确的值是零。

    排序算法的实现取决于供应商,并且可以返回不同的结果,具体取决于排序顺序,例如从开始或从结束。

    为了克服这个问题,你需要实现一个算法,它对相等的值返回零。

    const data = [{ name: "F", rank: 2 }, { name: "B", rank: null }, { name: "A", rank: 1 }, { name: "E", rank: null }, { name: "D", rank: null }, { name: "C", rank: 2 }]
    
    const nameSort = (a, b) => {
        const nameA = a.name.toUpperCase();
        const nameB = b.name.toUpperCase();
    
        return nameA > nameB || -(nameA < nameB);
    };
    
    const rankSort = (a, b) => (a.rank === null) - (b.rank === null) 
            
        
    
    console.log('name only', data.sort(nameSort));
    console.log('name and rank', data.sort(nameSort).sort(rankSort));
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    【讨论】:

      【解决方案2】:

      这是解决此问题的另一种方法。您可以结合使用Array.prototype.sort()Array.prototype.filter() 方法来获得最终结果。首先,对 name 属性应用字母排序。之后使用数组过滤方法将所有 null 'rank' 属性放在数组的末尾。

      const data = [
        {
          name: 'F',
          rank: 2,
        },
        {
          name: 'B',
          rank: null,
        },
        {
          name: 'A',
          rank: 1,
        },
        {
          name: 'E',
          rank: null,
        },
        {
          name: 'D',
          rank: null,
        },
        {
          name: 'C',
          rank: 2,
        },
      ];
      
      data.sort((x, y) => x.name.localeCompare(y.name));
      console.log('name only', data);
      
      const ret = [
        ...data.filter((x) => x.rank !== null),
        ...data.filter((x) => x.rank === null),
      ];
      console.log('name and rank', ret);

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-06-20
        • 2014-05-13
        • 2013-10-09
        • 1970-01-01
        • 1970-01-01
        • 2020-07-30
        • 2023-03-22
        相关资源
        最近更新 更多