Javascript 使用日期值按单个键对对象数组排序

Javascript 使用日期值按单个键对对象数组排序,javascript,arrays,object,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-05T0

我有一个包含多个键值对的对象数组,需要根据“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"
    }
]

最有效的方法是什么?

我在这里已经回答了一个非常类似的问题:

对于这个问题,我创建了一个小函数,它可以满足您的需要:

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));
    });
}
函数排序键(数组,键){
返回array.sort(函数(a,b){
变量x=a[key];变量y=b[key];
回报率((xy)?1:0);
});
}
您可以使用

下面是一个例子:
var-arr=[{
“更新时间”:“2012-01-01T06:25:24Z”,
“foo”:“bar”
},
{
“更新时间”:“2012-01-09T11:25:13Z”,
“foo”:“bar”
},
{
“更新时间”:“2012-01-05T04:13:24Z”,
“foo”:“bar”
}
]
arr.sort(函数(a,b){
var keyA=新日期(更新日期),
keyB=新日期(更新日期);
//比较两个日期
if(keyAkeyB)返回1;
返回0;
});

控制台日志(arr)按ISO格式的日期排序可能会很昂贵,除非您将客户端限制为最新和最好的浏览器,这样可以通过解析字符串按日期创建正确的时间戳

如果你对你的输入确信,并且你知道它将始终是yyyy-mm-ddThh:mm:ss和GMT(Z),你可以从每个成员中提取数字,并将它们像整数一样进行比较

array.sort(function(a,b){
    return a.updated_at.replace(/\D+/g,'')-b.updated_at.replace(/\D+/g,'');
});
如果日期的格式可能不同,您可能需要为iso挑战人员添加一些内容:

Date.fromISO: function(s){
    var day, tz,
    rx=/^(\d{4}\-\d\d\-\d\d([tT ][\d:\.]*)?)([zZ]|([+\-])(\d\d):(\d\d))?$/,
    p= rx.exec(s) || [];
    if(p[1]){
        day= p[1].split(/\D/).map(function(itm){
            return parseInt(itm, 10) || 0;
        });
        day[1]-= 1;
        day= new Date(Date.UTC.apply(Date, day));
        if(!day.getDate()) return NaN;
        if(p[5]){
            tz= (parseInt(p[5], 10)*60);
            if(p[6]) tz+= parseInt(p[6], 10);
            if(p[4]== '+') tz*= -1;
            if(tz) day.setUTCMinutes(day.getUTCMinutes()+ tz);
        }
        return day;
    }
    return NaN;
}
if(!Array.prototype.map){
    Array.prototype.map= function(fun, scope){
        var T= this, L= T.length, A= Array(L), i= 0;
        if(typeof fun== 'function'){
            while(i< L){
                if(i in T){
                    A[i]= fun.call(scope, T[i], i, T);
                }
                ++i;
            }
            return A;
        }
    }
}
}
Date.fromISO:函数{
var day,tz,
rx=/^(\d{4}-\d\d\-\d\d([tT][\d:\.]*)?)([zZ]|([+\-])(\d\d):(\d\d))?$/,
p=rx.exec | |[];
if(p[1]){
day=p[1]。拆分(/\D/)。映射(函数(itm){
返回parseInt(itm,10)| 0;
});
第[1]=1天;
日期=新日期(Date.UTC.apply(Date,day));
如果(!day.getDate())返回NaN;
if(p[5]){
tz=(parseInt(p[5],10)*60);
如果(p[6])tz+=parseInt(p[6],10);
如果(p[4]='+')tz*=-1;
if(tz)day.setUTCMinutes(day.getUTCMinutes()+tz);
}
回归日;
}
返回NaN;
}
if(!Array.prototype.map){
Array.prototype.map=函数(乐趣,范围){
var T=this,L=T.length,A=Array(L),i=0;
if(typeof fun=='function'){
而(i
这里有一个稍微修改过的版本,它按字符串的字母顺序排序,或按数字排序,并确保以大写字母开头的单词不会排序在以小写字母开头的单词之上(例如,“apple,Early”将按该顺序显示)

函数排序键(数组,键){
返回array.sort(函数(a,b){
var x=一个[键];
变量y=b[键];
如果(x的类型==“字符串”)
{
x=(“”+x).toLowerCase();
}
如果(y的类型==“字符串”)
{
y=(“”+y).toLowerCase();
}
回报率((xy)?1:0);
});
}

您可以创建一个闭包并以这种方式传递它

$.get('https://data.seattle.gov/resource/3k2p-39jp.json?$limit=10和$where=圆内(事故位置47.594972,-122.3315181609.34),
功能(响应){
var filter='event\u clearance\u group',//按键组名称排序
数据=响应;
变量比较=函数(过滤器){
返回函数(a,b){
变量a=a[过滤器],
b=b[过滤器];
if(ab){
返回1;
}否则{
返回0;
}
};
};
过滤器=比较(过滤器);//设置过滤器
console.log(data.sort(filter));
});

使用下划线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");
返回一个新数组

参考和
lodash文档

通过ES2015支持,可以通过以下方式完成:

foo.sort((a, b) => a.updated_at < b.updated_at ? -1 : 1)
foo.sort((a,b)=>a.updated\u at
该方法对数组中的元素进行适当排序并返回数组。小心,因为它不是。用于不可变排序

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

用于:

用于:

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

用于:

用于:

在撰写本文时,现代浏览器不支持ES6。要在现代浏览器中使用ES6,请使用将代码传输到ES5。预计在不久的将来,浏览器将支持ES6

应接收三种可能结果之一的返回值:

  • 正数(第一项>第二项)
  • 负数(第一项<第二项)
  • 如果两项相等,则为0
请注意,内联函数的返回值可以是任意值 正数或负数。Array.Sort()不关心 返回号码是。它只关心返回值是否为正, 负或零

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

您也可以这样写:

import sort from 'immutable-sort';
const array = [1, 5, 2, 4, 3];
const sortedArray = sort(array);
从您看到的导入是在ES6中包含javascript的一种新方法,它使您的代码看起来非常干净。我个人最喜欢的

不可变排序不会改变源数组,而是返回一个新数组。建议使用
const
foo.sort((a, b) => a.updated_at < b.updated_at ? -1 : 1)
arr.sort((a,b) => new Date(a.updated_at).getTime() - new Date(b.updated_at).getTime());
arr.sort(function(a,b){ 
 return new Date(a.updated_at).getTime() - new Date(b.updated_at).getTime();
});
arr.sort((a,b) => a.updated_at - b.updated_at);
arr.sort(function(a,b){ 
 return a.updated_at - b.updated_at;
});
const sort = require('immutable-sort');
const array = [1, 5, 2, 4, 3];
const sortedArray = sort(array);
import sort from 'immutable-sort';
const array = [1, 5, 2, 4, 3];
const sortedArray = sort(array);
arr.sort(function(a, b){
    var diff = new Date(a.updated_at) - new Date(b.updated_at);
    return diff/(Math.abs(diff)||1);
});
arr.sort((a, b) => {
    var diff = new Date(a.updated_at) - new Date(b.updated_at);
    return diff/(Math.abs(diff)||1);
});
arr.sort((a, b) => {
   const dateA = new Date(a.updated_at);
   const dateB = new Date(b.updated_at);
   return dateA - dateB;
});
var months = [
    {
        "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"
    }];
months.sort((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;
});
console.log(months);
function sortBy(list, keyFunc) {
  return list.sort((a,b) => keyFunc(a) - keyFunc(b));
}

sortBy([{"key": 2}, {"key": 1}], o => o["key"])
Array.prototype.sortBy = function(key_func, reverse=false){
    return this.sort( (a, b) => {
        var keyA = key_func(a),
            keyB = key_func(b);
        if(keyA < keyB) return reverse? 1: -1;
        if(keyA > keyB) return reverse? -1: 1;
        return 0;
    }); 
}
var arr = [ {date: "01/12/00", balls: {red: "a8",  blue: 10}},
            {date: "12/13/05", balls: {red: "d6" , blue: 11}},
            {date: "03/02/04", balls: {red: "c4" , blue: 15}} ]
arr.sortBy(el => el.balls.red)
/* would result in
[ {date: "01/12/00", balls: {red: "a8", blue: 10}},
  {date: "03/02/04", balls: {red: "c4", blue: 15}},
  {date: "12/13/05", balls: {red: "d6", blue: 11}} ]
*/
arr.sortBy(el => new Date(el.date), true)   // second argument to reverse it
/* would result in
[ {date: "12/13/05", balls: {red: "d6", blue:11}},
  {date: "03/02/04", balls: {red: "c4", blue:15}},
  {date: "01/12/00", balls: {red: "a8", blue:10}} ]
*/
arr.sortBy(el => el.balls.blue + parseInt(el.balls.red[1]))
/* would result in
[ {date: "12/13/05", balls: {red: "d6", blue:11}},    // red + blue= 17
  {date: "01/12/00", balls: {red: "a8", blue:10}},    // red + blue= 18
  {date: "03/02/04", balls: {red: "c4", blue:15}} ]   // red + blue= 19
*/
[
    {
        "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"
    }
]
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;
});
[
    {
        "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"
    }
]
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;
});
[
    {
        "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"
    }
]
export type SortType = 'string' | 'number' | 'date';
export type SortingOrder = 'asc' | 'desc';

export interface SortOptions {
  sortByKey: string;
  sortType?: SortType;
  sortingOrder?: SortingOrder;
}


class CustomSorting {
    static sortArrayOfObjects(fields: SortOptions[] = [{sortByKey: 'value', sortType: 'string', sortingOrder: 'desc'}]) {
        return (a, b) => fields
          .map((field) => {
            if (!a[field.sortByKey] || !b[field.sortByKey]) {
              return 0;
            }

            const direction = field.sortingOrder === 'asc' ? 1 : -1;

            let firstValue;
            let secondValue;

            if (field.sortType === 'string') {
              firstValue = a[field.sortByKey].toUpperCase();
              secondValue = b[field.sortByKey].toUpperCase();
            } else if (field.sortType === 'number') {
              firstValue = parseInt(a[field.sortByKey], 10);
              secondValue = parseInt(b[field.sortByKey], 10);
            } else if (field.sortType === 'date') {
              firstValue = new Date(a[field.sortByKey]);
              secondValue = new Date(b[field.sortByKey]);
            }
            return firstValue > secondValue ? direction : firstValue < secondValue ? -(direction) : 0;

          })
          .reduce((pos, neg) => pos ? pos : neg, 0);
      }
    }
}
const sortOptions = [{
      sortByKey: 'anyKey',
      sortType: 'string',
      sortingOrder: 'asc',
    }];

arrayOfObjects.sort(CustomSorting.sortArrayOfObjects(sortOptions));
//example:
//array: [{name: 'idan', workerType: '3'}, {name: 'stas', workerType: '5'}, {name: 'kirill', workerType: '2'}]
//keyField: 'workerType'
// keysArray: ['4', '3', '2', '5', '6']
sortByArrayOfKeys = (array, keyField, keysArray) => {
    array.sort((a, b) => {
        const aIndex = keysArray.indexOf(a[keyField])
        const bIndex = keysArray.indexOf(b[keyField])
        if (aIndex < bIndex) return -1;
        if (aIndex > bIndex) return 1;
        return 0;
    })
}