javascript按两个数字字段排序数组

grouperArray.sort(function (a, b) {
    var aSize = a.gsize;
    var bSize = b.gsize;
    var aLow = a.glow;
    var bLow = b.glow;
    console.log(aLow + " | " + bLow);      
    return (aSize < bSize) ? -1 : (aSize > bSize) ? 1 : 0;
});

上面的代码通过GSIZE – 最小到最大的数组对数组进行排序。它运作良好,但如果GSIZE是一样的,我希望它能够通过发光排序。

谢谢。

回答 17

  1. 赞同 189

    grouperArray.sort(function (a, b) {   
        return a.gsize - b.gsize || a.glow - b.glow;
    });
    

    Shorter版本

    Anmorozov23
    换句话说!帮助我一起放置更复杂的解决方案..stackoverflow.com/questions/6101475/...Joseph Poirier
    如果你很高兴使用新的Afanasii Kurakin
    你解释在这里的逻辑?!。它为我工作了sort an array with a key's value first然后sort the result with another key's value KTM
    @ KTM逻辑如下:如果GSIZE都相等,则条件的第一部分等于0,被认为是假的,并且执行条件的第二部分。Scalpweb
    @ scarpweb是的:)因此这有效地对数组进行排序,一个右一个键,右一个键?!好玩的KTM
  2. 赞同 122

    grouperArray.sort(function (a, b) {
        var aSize = a.gsize;
        var bSize = b.gsize;
        var aLow = a.glow;
        var bLow = b.glow;
        console.log(aLow + " | " + bLow);
    
        if(aSize == bSize)
        {
            return (aLow < bLow) ? -1 : (aLow > bLow) ? 1 : 0;
        }
        else
        {
            return (aSize < bSize) ? -1 : 1;
        }
    });
    

    CHRIS EBERLE
    更简单地使用箭头语法,而不诉诸于其他答案中显示的非明显技术:grouperArray.sort((a, b) => a.gsize == b.gsize ? a.glow - b.glow : a.gsize - b.gsize.要使代码更容易理解,我们会保持明确的测试==.Toolmakersteve
    My善良......谢谢@ToolMakerSteve。Slbox
    贴补和有效Anthony
  3. 赞同 45

    grouperArray.sort((a, b) => a.gsize - b.gsize || a.glow - b.glow);
    

    向缩短版本使用arrow语法!

    Vinorth
    最简洁,最伸展,完美!律师
    Even shorter, take out the spaces: grouperArray.sort((a,b)=>a.gsize-b.gsize||a.glow-b.glow);Captain太棒了
    if you want to understand why that works you might wanna look at medium.com/@safareli/psss-ordering-is-a-ynoid-61a4029387e.SAFARLI
  4. 赞同 15

    我意识到这是在一段时间之前问过的,但我以为我会添加我的解决方案。

    此函数动态生成排序方法。只需提供每个可排序的子属性名称,添加+/-表示升序或降序。超级可用性,并且不需要了解您放在一起的数据结构。可以制作白痴证明 - 但似乎似乎是必要的。

    function getSortMethod(){
        var _args = Array.prototype.slice.call(arguments);
        return function(a, b){
            for(var x in _args){
                var ax = a[_args[x].substring(1)];
                var bx = b[_args[x].substring(1)];
                var cx;
    
                ax = typeof ax == "string" ? ax.toLowerCase() : ax / 1;
                bx = typeof bx == "string" ? bx.toLowerCase() : bx / 1;
    
                if(_args[x].substring(0,1) == "-"){cx = ax; ax = bx; bx = cx;}
                if(ax != bx){return ax < bx ? -1 : 1;}
            }
        }
    }
    

    Example使用:

    Items.sort(getortmethod(' - price','+ priority','+ name'));

    this would sort items with lowest priceFirst,带有最高的物品的关系priority.物品突破了进一步的关系name

    项目中的位置是:

    var items = [
        { name: "z - test item", price: "99.99", priority: 0, reviews: 309, rating: 2 },
        { name: "z - test item", price: "1.99", priority: 0, reviews: 11, rating: 0.5 },
        { name: "y - test item", price: "99.99", priority: 1, reviews: 99, rating: 1 },
        { name: "y - test item", price: "0", priority: 1, reviews: 394, rating: 3.5 },
        { name: "x - test item", price: "0", priority: 2, reviews: 249, rating: 0.5 } ...
    ];
    

    Live Demo:http://gregtaff.com/misc/multi_field_sort/

    ET:用Chrome解决问题。

    NIHLTON
    This is brilliantauzure
    Genius答案!Marius
    对于类型来(因为没有得到一个error TS2554: Expected 0 arguments, but got ..)在此处使用语法:stackoverflow.com/a/4116634/5287221Chananel P
  5. 赞同 7

    I expect the operator ((aSize < bSize) ? -1 : (aSize > bSize) ? 1 : 0;) has you confused. You should check out the link to understand it better.

    Until那么,这里的代码已经完全吹入满/别的。

    grouperArray.sort(function (a, b) {
        if (a.gsize < b.gsize)
        {
            return -1;
        }
        else if (a.gsize > b.gsize)
        {
            return 1;
        }
        else
        {
            if (a.glow < b.glow)
            {
                return -1;
            }
            else if (a.glow > b.glow)
            {
                return 1;
            }
            return 0;
        }
    });
    

    John绿色
  6. 赞同 6

    这是那些可能想要更多通用的人的实施,这将适用于任何数量的字段。

    Array.prototype.sortBy = function (propertyName, sortDirection) {
    
        var sortArguments = arguments;
        this.sort(function (objA, objB) {
    
            var result = 0;
            for (var argIndex = 0; argIndex < sortArguments.length && result === 0; argIndex += 2) {
    
                var propertyName = sortArguments[argIndex];
                result = (objA[propertyName] < objB[propertyName]) ? -1 : (objA[propertyName] > objB[propertyName]) ? 1 : 0;
    
                //Reverse if sort order is false (DESC)
                result *= !sortArguments[argIndex + 1] ? 1 : -1;
            }
            return result;
        });
    
    }
    

    或者,您可以指定任意数量的属性名称/排序方向:

    var arr = [{
      LastName: "Doe",
      FirstName: "John",
      Age: 28
    }, {
      LastName: "Doe",
      FirstName: "Jane",
      Age: 28
    }, {
      LastName: "Foo",
      FirstName: "John",
      Age: 30
    }];
    
    arr.sortBy("LastName", true, "FirstName", true, "Age", false);
    //Will return Jane Doe / John Doe / John Foo
    
    arr.sortBy("Age", false, "LastName", true, "FirstName", false);
    //Will return John Foo / John Doe / Jane Doe
    

    the_black_smurf
  7. 赞同 3

    grouperArray.sort(function (a, b) {
      var aSize = a.gsize;
      var bSize = b.gsize;
      var aLow = a.glow;
      var bLow = b.glow;
      console.log(aLow + " | " + bLow);      
      return (aSize < bSize) ? -1 : (aSize > bSize) ? 1 : ( (aLow < bLow ) ? -1 : (aLow > bLow ) ? 1 : 0 );
    });
    

    Silex
  8. 赞同 3

    grouperArray.sort(function (a, b) {
         var aSize = a.gsize;     
         var bSize = b.gsize;     
         var aLow = a.glow;
         var bLow = b.glow;
         console.log(aLow + " | " + bLow);
         return (aSize < bSize) ? -1 : (aSize > bSize) ? 1 : (aLow < bLow) ? -1 : (aLow > bLow) ? 1 : 0); }); 
    

    tim威廉姆斯
  9. 赞同 3

    一种实现,它使用递归根据从1到无限的任何排序字段排序。您将其传递一个结果数组,该数组是要排序的结果对象数组,以及排序数组,它是定义排序的排序对象数组。每个排序对象必须具有“选择”键,以便其排序和“订单”键,键和“顺序”键,该键是指示“升序”或“降序”的字符串。

    sortMultiCompare = (a, b, sorts) => {
        let select = sorts[0].select
        let order = sorts[0].order
        if (a[select] < b[select]) {
            return order == 'ascending' ? -1 : 1
        } 
        if (a[select] > b[select]) {
            return order == 'ascending' ? 1 : -1
        }
        if(sorts.length > 1) {
            let remainingSorts = sorts.slice(1)
            return this.sortMultiCompare(a, b, remainingSorts)
        }
        return 0
    }
    
    sortResults = (results, sorts) => {
        return results.sort((a, b) => {
            return this.sortMultiCompare(a, b, sorts)
        })
    }
    
    // example inputs
    const results = [
        {
            "LastName": "Doe",
            "FirstName": "John",
            "MiddleName": "Bill"
        },
        {
            "LastName": "Doe",
            "FirstName": "Jane",
            "MiddleName": "Bill"
        },
        {
            "LastName": "Johnson",
            "FirstName": "Kevin",
            "MiddleName": "Bill"
        }
    ]
    
    const sorts = [
        {
            "select": "LastName",
            "order": "ascending"
        },
        {
            "select": "FirstName",
            "order": "ascending"
        },
        {
            "select": "MiddleName",
            "order": "ascending"
        }    
    ]
    
    // call the function like this:
    let sortedResults = sortResults(results, sorts)
    

    Benjamin Portman
  10. 赞同 3

    使用多个键执行此操作的动态方式:

    • 从每个Col /键的默认值
    • 按顺序或逆转它
    • 一种基于索引的每个对象的权重zeropad(值)键值
    • 使用CacleStated权重

    enter image description here

    Object.defineProperty(Array.prototype, 'orderBy', {
    value: function(sorts) { 
        sorts.map(sort => {            
            sort.uniques = Array.from(
                new Set(this.map(obj => obj[sort.key]))
            );
    
            sort.uniques = sort.uniques.sort((a, b) => {
                if (typeof a == 'string') {
                    return sort.inverse ? b.localeCompare(a) : a.localeCompare(b);
                }
                else if (typeof a == 'number') {
                    return sort.inverse ? (a < b) : (a > b ? 1 : 0);
                }
                else if (typeof a == 'boolean') {
                    let x = sort.inverse ? (a === b) ? 0 : a? -1 : 1 : (a === b) ? 0 : a? 1 : -1;
                    return x;
                }
                return 0;
            });
        });
    
        const weightOfObject = (obj) => {
            let weight = "";
            sorts.map(sort => {
                let zeropad = `${sort.uniques.length}`.length;
                weight += sort.uniques.indexOf(obj[sort.key]).toString().padStart(zeropad, '0');
            });
            //obj.weight = weight; // if you need to see weights
            return weight;
        }
    
        this.sort((a, b) => {
            return weightOfObject(a).localeCompare( weightOfObject(b) );
        });
    
        return this;
    }
    });
    

    使用:

    // works with string, number and boolean
    let sortered = your_array.orderBy([
        {key: "type", inverse: false}, 
        {key: "title", inverse: false},
        {key: "spot", inverse: false},
        {key: "internal", inverse: true}
    ]);
    

    enter image description here

    Leonardo Filipe
  11. 赞同 1

    This is what I use

    function sort(a, b) {
        var _a = "".concat(a.size, a.glow);
        var _b = "".concat(b.size, b.glow);
        return _a < _b;
    }
    

    将这两个项目作为字符串,它们将按字符串值排序。如果您希望您可以将_a和_b与parseint一起包装以将它们与数字进行比较,如果您知道它们将是数值的。

    BlockLoop
  12. 赞同 1

    如果您有优先级排序密钥的情况,则是该案例的解决方案,这可能不存在于某些特定项目中,因此您必须按回退键排序。

    输入数据示例(id2.IS优先级排序密钥):

    const arr = [
        {id: 1},
        {id: 2, id2: 3},
        {id: 4},
        {id: 3},
        {id: 10, id2: 2},
        {id: 7},
        {id: 6, id2: 1},
        {id: 5},
        {id: 9, id2: 2},
        {id: 8},
    ];
    

    输出应该是:

    [ { id: 6, id2: 1 },
      { id: 9, id2: 2 },
      { id: 10, id2: 2 },
      { id: 2, id2: 3 },
      { id: 1 },
      { id: 3 },
      { id: 4 },
      { id: 5 },
      { id: 7 },
      { id: 8 } ]
    

    比较器功能将是:

    arr.sort((a,b) => {
      if(a.id2 || b.id2) {
        if(a.id2 && b.id2) {
          if(a.id2 === b.id2) {
            return a.id - b.id;
          }
          return a.id2 - b.id2;
        }
        return a.id2 ? -1 : 1;
      }
      return a.id - b.id
    });
    

    P.S.如果是ID.ID2Can是零,考虑使用typeof.

    Den L
  13. 赞同 1

    Let的简化。

    您有一系列数组:

    let tmp = [
        [0, 1],
        [2, 1],
        [1, 1],
        [0, 0],
        [2, 0],
        [1, 0],
        [0, 2],
        [2, 2],
        [1, 2],
    ]
    

    Executing:

    tmp.sort((a, b) => {
        if (a[1] != b[1])
            return a[1] - b[1];
        else
            return a[0] - b[0];
    })
    

    威尔产量:

    [
        [0, 0],
        [1, 0],
        [2, 0],
        [0, 1],
        [1, 1],
        [2, 1],
        [0, 2],
        [1, 2],
        [2, 2]
    ]
    

    Ulf Aslak
  14. 赞同 0

    grouperArray.sort(
      function(a,b){return a.gsize == b.gsize ? a.glow - b.glow : a.gsize - b.gsize}
    );
    

    IC3B3RG
  15. 赞同 0

    grouperArray.sort(function (a, b) {
        var aSize = a.gsize;
        var bSize = b.gsize;
        if (aSize !== aSize)
            return aSize - bSize;
        return a.glow - b.glow;
    });
    

    not tested, but I think that should work.

    xander
  16. 赞同 0

    在我的情况下,我按Param“重要”和“日期”排序通知列表

    • Step 1:我通过“重要”和不重要的通知

      let importantNotifications = notifications.filter(
              (notification) => notification.isImportant);
      
        let unImportantNotifications = notifications.filter(
              (notification) => !notification.isImportant);
      
    • Step 2:我按日期排序

        sortByDate = (notifications) => {
        return notifications.sort((notificationOne, notificationTwo) => {
          return notificationOne.date - notificationTwo.date;
        });
      };
      
    • Step 3:合并它们

      [
          ...this.sortByDate(importantNotifications),
          ...this.sortByDate(unImportantNotifications),
        ];
      

    PHạMHùng
  17. 赞同 0

    If you're happy to use the new tidy.js包你可以用它来实现这一目标

    tidy(input_array,
      arrange(['var1', desc('var2')])
    );
    

    地理