使用日期值按单键对对象数组进行排序

235 javascript arrays object

我有一组具有多个键值对的对象,我需要根据'updated_at'对它们进行排序:

[
    {
        "updated_at" : "2012-01-01T06:25:24Z",
        "foo" : "bar"
    },
    {
        "updated_at" : "2012-01-09T11:25:13Z",
        "foo" : "bar"
    },
    {
        "updated_at" : "2012-01-05T04:13:24Z",
        "foo" : "bar"
    }
]
Run Code Online (Sandbox Code Playgroud)

最有效的方法是什么?

Roc*_*mat 305

你可以用Array.sort.

这是一个(未经测试的)示例:

arr.sort(function(a, b){
    var keyA = new Date(a.updated_at),
        keyB = new Date(b.updated_at);
    // Compare the 2 dates
    if(keyA < keyB) return -1;
    if(keyA > keyB) return 1;
    return 0;
});
Run Code Online (Sandbox Code Playgroud)

  • 难道你不能使用`keyA - keyB`(或者可能是`keyB - keyA`)?日期对象有一个`valueOf()`方法. (17认同)
  • 如果您想根据键中的数值进行排序,那么这个 ES6 单行代码可能会有所帮助。`yourArr.sort((a, b) =&gt; a.yourNumericOrderingKey &gt; b.yourNumericOrderingKey)`。就我而言,我必须根据主数组对象内部的“order”键进行排序。 (3认同)

Dav*_*ner 152

我已经回答了一个非常类似的问题:简单的函数来排序对象数组

对于这个问题,我创建了这个可能做你想做的小功能:

function sortByKey(array, key) {
    return array.sort(function(a, b) {
        var x = a[key]; var y = b[key];
        return ((x < y) ? -1 : ((x > y) ? 1 : 0));
    });
}
Run Code Online (Sandbox Code Playgroud)

  • 你,先生,是男人.http://blogs.citypages.com/blotter/assets_c/2009/02/YouDaManJesus-thumb-500x435.jpg (11认同)
  • 要反转像这样的排序函数,只需将结果乘以`-1` :) (4认同)
  • 或者只是获取输出并使用`array = array.reverse()`函数. (4认同)
  • 为了使它不区分大小写,可以将.toLowerCase()添加到x和y变量中 (3认同)
  • 你怎么扭转这个? (2认同)

Pat*_*hon 24

所述的Array.sort()方法进行排序的阵列的代替元素并返回数组.注意Array.sort(),因为它不是不可变的.对于不可变排序使用不可变排序.

此方法是使用updated_atISO格式的当前对数组进行排序.我们使用new Data(iso_string).getTime()将ISO时间转换为Unix时间戳.Unix时间戳是一个我们可以进行简单数学运算的数字.我们减去结果的第一个和第二个时间戳; 如果第一个时间戳大于第二个时间戳,则返回数字为正数.如果第二个数字大于第一个数字,则返回值将为负数.如果两者相同,则返回值为零.这完全符合内联函数所需的返回值.

对于ES6:

arr.sort((a,b) => new Date(a.updated_at).getTime() - new Date(b.updated_at).getTime());
Run Code Online (Sandbox Code Playgroud)

对于ES5:

arr.sort(function(a,b){ 
 return new Date(a.updated_at).getTime() - new Date(b.updated_at).getTime();
});
Run Code Online (Sandbox Code Playgroud)

如果将您更改updated_at为unix时间戳,则可以执行以下操作:

对于ES6:

arr.sort((a,b) => a.updated_at - b.updated_at);
Run Code Online (Sandbox Code Playgroud)

对于ES5:

arr.sort(function(a,b){ 
 return a.updated_at - b.updated_at;
});
Run Code Online (Sandbox Code Playgroud)

在本文发表时,现代浏览器不支持ES6.要在现代浏览器中使用ES6,请使用babel将代码转换为ES5.预计在不久的将来浏览器支持ES6.

Array.sort()应该接收3个可能结果之一的返回值:

  • 正数(第一项>第二项)
  • 负数(第一项<第二项)
  • 如果两个项目相等则为0

请注意,内联函数的返回值可以是任何正数或负数.Array.Sort()不关心返回数是多少.它只关心返回值是正数,负数还是零.

对于不可变排序:( ES6中的示例)

const sort = require('immutable-sort');
const array = [1, 5, 2, 4, 3];
const sortedArray = sort(array);
Run Code Online (Sandbox Code Playgroud)

你也可以这样写:

import sort from 'immutable-sort';
const array = [1, 5, 2, 4, 3];
const sortedArray = sort(array);
Run Code Online (Sandbox Code Playgroud)

您看到的导入是一种在ES6中包含javascript并使您的代码看起来非常干净的新方法.我个人的最爱.

不可变排序不会改变源数组,而是返回一个新数组.使用const建议不可变的数据.


Bra*_*rks 18

这是@David Brainer-Bankers答案的略微修改版本,按字母顺序按字母顺序排序,或按数字按数字排序,并确保以大写字母开头的单词不会以小写字母开头的单词排序(例如"apple,Early"将按此顺序显示).

function sortByKey(array, key) {
    return array.sort(function(a, b) {
        var x = a[key];
        var y = b[key];

        if (typeof x == "string")
        {
            x = (""+x).toLowerCase(); 
        }
        if (typeof y == "string")
        {
            y = (""+y).toLowerCase();
        }

        return ((x < y) ? -1 : ((x > y) ? 1 : 0));
    });
}
Run Code Online (Sandbox Code Playgroud)

  • 如果[key]和b [key]不是两个字符串,则建议的解决方案可能会出错.我建议用y =(""+ y).toLowerCase()替换y = y.toLowerCase() (3认同)

Moh*_*eer 13

使用下划线js或lodash,

var arrObj = [
    {
        "updated_at" : "2012-01-01T06:25:24Z",
        "foo" : "bar"
    },
    {
        "updated_at" : "2012-01-09T11:25:13Z",
        "foo" : "bar"
    },
    {
        "updated_at" : "2012-01-05T04:13:24Z",
        "foo" : "bar"
    }
];

arrObj = _.sortBy(arrObj,"updated_at");
Run Code Online (Sandbox Code Playgroud)

_.sortBy() 返回一个新数组

参考http://underscorejs.org/#sortBy和lodash docs https://lodash.com/docs#sortBy


小智 10

我来得有点晚了,但在 2021 年,正确的答案是使用Intl.Collator. updated_at是 ISO-8601 字符串,因此可作为字符串排序。转换为 aDate是浪费时间,if手动执行比较以返回 0、1 或 -1 也是浪费时间。

const arr = [
  {
    "updated_at": "2012-01-01T06:25:24Z",
    "foo": "bar"
  },
  {
    "updated_at": "2012-01-09T11:25:13Z",
    "foo": "bar"
  },
  {
    "updated_at": "2012-01-05T04:13:24Z",
    "foo": "bar"
  }
];

const { compare } = Intl.Collator('en-US');
arr.sort((a, b) => compare(a.updated_at, b.updated_at));
Run Code Online (Sandbox Code Playgroud)

Intl.Collator返回一个可以用作compareFunctionfor的函数#Array.sort。因为我们要对对象进行排序,所以我们compare使用要排序的键的值进行调用。

请注意,如果我们要对字符串数组进行排序,我们可以简单地这样做:

arr.sort(compare);
Run Code Online (Sandbox Code Playgroud)

另请注意,正如其他人指出的那样,sort会改变原始数组。如果这是不可取的,您可能需要先克隆它。2021 年,您可以执行以下操作:

[...arr].sort((a, b) => compare(a.updated_at, b.updated_at));
Run Code Online (Sandbox Code Playgroud)


Fyo*_*dor 6

至于今天,@knowbody ( /sf/answers/2969327441/ ) 和 @Rocket Hazmat ( /sf/answers/618625801/ ) 的答案可以结合起来提供 ES2015 支持和正确的日期处理:

var arr = [{
    "updated_at": "2012-01-01T06:25:24Z",
    "foo": "bar"
  },
  {
    "updated_at": "2012-01-09T11:25:13Z",
    "foo": "bar"
  },
  {
    "updated_at": "2012-01-05T04:13:24Z",
    "foo": "bar"
  }
];
arr.sort((a, b) => {
   const dateA = new Date(a.updated_at);
   const dateB = new Date(b.updated_at);
   return dateA - dateB;
});
Run Code Online (Sandbox Code Playgroud)


Ana*_*n K 6

数据导入

[
    {
        "gameStatus": "1",
        "userId": "c02cfb18-ae66-430b-9524-67d9dd8f6a50",
        "created_at": "2018-12-20 11:32:04"
    },
    {
        "gameStatus": "0",
        "userId": "c02cfb18-ae66-430b-9524-67d9dd8f6a50",
        "created_at": "2018-12-19 18:08:24"
    },
    {
        "gameStatus": "2",
        "userId": "c02cfb18-ae66-430b-9524-67d9dd8f6a50",
        "created_at": "2018-12-19 18:35:40"
    },
    {
        "gameStatus": "0",
        "userId": "c02cfb18-ae66-430b-9524-67d9dd8f6a50",
        "created_at": "2018-12-19 10:42:53"
    },
    {
        "gameStatus": "2",
        "userId": "c02cfb18-ae66-430b-9524-67d9dd8f6a50",
        "created_at": "2018-12-20 10:54:09"
    },
    {
        "gameStatus": "0",
        "userId": "1a2fefb0-5ae2-47eb-82ff-d1b2cc27875a",
        "created_at": "2018-12-19 18:46:22"
    },
    {
        "gameStatus": "1",
        "userId": "7118ed61-d8d9-4098-a81b-484158806d21",
        "created_at": "2018-12-20 10:50:48"
    }
]
Run Code Online (Sandbox Code Playgroud)

FOR 升序

arr.sort(function(a, b){
    var keyA = new Date(a.updated_at),
        keyB = new Date(b.updated_at);
    // Compare the 2 dates
    if(keyA < keyB) return -1;
    if(keyA > keyB) return 1;
    return 0;
});
Run Code Online (Sandbox Code Playgroud)

升序示例

[
    {
        "gameStatus": "0",
        "userId": "c02cfb18-ae66-430b-9524-67d9dd8f6a50",
        "created_at": "2018-12-19 10:42:53"
    },
    {
        "gameStatus": "0",
        "userId": "c02cfb18-ae66-430b-9524-67d9dd8f6a50",
        "created_at": "2018-12-19 18:08:24"
    },
    {
        "gameStatus": "2",
        "userId": "c02cfb18-ae66-430b-9524-67d9dd8f6a50",
        "created_at": "2018-12-19 18:35:40"
    },
    {
        "gameStatus": "0",
        "userId": "1a2fefb0-5ae2-47eb-82ff-d1b2cc27875a",
        "created_at": "2018-12-19 18:46:22"
    },
    {
        "gameStatus": "1",
        "userId": "7118ed61-d8d9-4098-a81b-484158806d21",
        "created_at": "2018-12-20 10:50:48"
    },
    {
        "gameStatus": "2",
        "userId": "c02cfb18-ae66-430b-9524-67d9dd8f6a50",
        "created_at": "2018-12-20 10:54:09"
    },
    {
        "gameStatus": "1",
        "userId": "c02cfb18-ae66-430b-9524-67d9dd8f6a50",
        "created_at": "2018-12-20 11:32:04"
    }
]
Run Code Online (Sandbox Code Playgroud)

FOR 降序

arr.sort(function(a, b){
    var keyA = new Date(a.updated_at),
        keyB = new Date(b.updated_at);
    // Compare the 2 dates
    if(keyA > keyB) return -1;
    if(keyA < keyB) return 1;
    return 0;
});
Run Code Online (Sandbox Code Playgroud)

降序示例

[
    {
        "gameStatus": "1",
        "userId": "c02cfb18-ae66-430b-9524-67d9dd8f6a50",
        "created_at": "2018-12-20 11:32:04"
    },
    {
        "gameStatus": "2",
        "userId": "c02cfb18-ae66-430b-9524-67d9dd8f6a50",
        "created_at": "2018-12-20 10:54:09"
    },
    {
        "gameStatus": "1",
        "userId": "7118ed61-d8d9-4098-a81b-484158806d21",
        "created_at": "2018-12-20 10:50:48"
    },
    {
        "gameStatus": "0",
        "userId": "1a2fefb0-5ae2-47eb-82ff-d1b2cc27875a",
        "created_at": "2018-12-19 18:46:22"
    },
    {
        "gameStatus": "2",
        "userId": "c02cfb18-ae66-430b-9524-67d9dd8f6a50",
        "created_at": "2018-12-19 18:35:40"
    },
    {
        "gameStatus": "0",
        "userId": "c02cfb18-ae66-430b-9524-67d9dd8f6a50",
        "created_at": "2018-12-19 18:08:24"
    },
    {
        "gameStatus": "0",
        "userId": "c02cfb18-ae66-430b-9524-67d9dd8f6a50",
        "created_at": "2018-12-19 10:42:53"
    }
]
Run Code Online (Sandbox Code Playgroud)


kno*_*ody 5

借助ES2015支持,可以通过以下方式实现:

foo.sort((a, b) => a.updated_at < b.updated_at ? -1 : 1)
Run Code Online (Sandbox Code Playgroud)

  • 如果将 &lt; 替换为 - 并删除 '? 则不需要内联 -1 : 1" 您将得到有效的返回值。此示例移动可能相等的项目,因此可能会产生意外结果。对于相等的项目,应返回 0。 (2认同)