2012-01-12 2 views
143

У меня есть массив объектов с несколькими ключевыми парами значений, и мне нужно, чтобы отсортировать их на основе «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" 
    } 
] 

Что наиболее эффективный способ Сделай так?

+0

пользовательские функции: http://stackoverflow.com/questions/777597/sorting-an-associative-array-in-php –

+0

@Topener Эта ссылка выглядит на вопрос о PHP –

+0

моя ошибка .. не читал правильно –

ответ

207

Вы можете использовать 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; 
}); 
+11

Не могли бы вы использовать 'keyA - keyB' (или, возможно,' keyB - keyA')? Объекты date имеют метод 'valueOf()'. – soktinpk

+0

@soktinpk: Да. Это должно сработать. –

+0

var keyA = новая дата (a.updated_at), обратите внимание, что есть «,» ее необходимо заменить на «;». Другой мудрый он будет бросать одну ошибку – brk

121

я уже ответил на очень похожий вопрос здесь: Simple function to sort an array of objects

Для этого вопроса я создал эту маленькую функцию, которая может делать то, что вы хотите:

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)); 
    }); 
} 
+8

Ты, сэр, мужчина. http://blogs.citypages.com/blotter/assets_c/2009/02/YouDaManJesus-thumb-500x435.jpg – Dom

+2

Как бы вы отменили это? –

+3

Чтобы сделать его нечувствительным к регистру, вы можете добавить .toLowerCase() в переменные x и y –

1

Сортировка с помощью ISO отформатированных дат могут быть дорогими, если вы не ограничивать клиент последние и лучшие браузеры, которые могут создать правильную метку времени по дате-анализ Струна.

Если вы уверены вашего входа, и вы знаете всегда будет гггг-мм-DDThh: мм: сс и GMT (Z) можно извлечь цифры от каждого члена и сравнить их как целые числа

array.sort(function(a,b){ 
    return a.updated_at.replace(/\D+/g,'')-b.updated_at.replace(/\D+/g,''); 
}); 

Если дата может быть отформатирован по-другому, вы можете добавить что-то для людей изо вызов:

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; 
     } 
    } 
} 
} 
+2

Не могли бы вы использовать ['Date.parse'] (https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date/parse)? –

14

Вот слегка измененная версия @David Brainer-Bankers answer, который сортируется по алфавиту по строкам или численно по числу и гарантирует, что слова, начинающиеся с прописных букв, не сортируются над словами, начинающимися с буквы нижнего регистра (например, «яблоко, ранний» будет отображаться в этом порядке).

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)); 
    }); 
} 
+2

Предлагаемое решение может дать ошибку, если [ключ] и b [ключ] не являются обеими строками. Я предлагаю заменить y = y.toLowerCase() на y = ("" + y) .toLowerCase() – user8074

0

Вы можете создать укупорочное и передать его таким образом here is my example working

$.get('https://data.seattle.gov/resource/3k2p-39jp.json?$limit=10&$where=within_circle(incident_location, 47.594972, -122.331518, 1609.34)', 
    function(responce) { 

    var filter = 'event_clearance_group', //sort by key group name 
    data = responce; 

    var compare = function (filter) { 
     return function (a,b) { 
      var a = a[filter], 
       b = b[filter]; 

      if (a < b) { 
       return -1; 
      } else if (a > b) { 
       return 1; 
      } else { 
       return 0; 
      } 
     }; 
    }; 

    filter = compare(filter); //set filter 

    console.log(data.sort(filter)); 
}); 
8

Использование подчеркивания 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"); 

_.sortBy() возвращает новый массив

сослаться http://underscorejs.org/#sortBy и lodash документы https://lodash.com/docs#sortBy

0

С поддержкой ES2015 это может быть сделано:

foo.sort((a, b) => a.updated_at < b.updated_at ? -1 : 1) 
+1

нет необходимости в inline, если заменить <на - и удалить "? -1: 1 "вы получите действительный доход. В этом примере перемещаются элементы, которые могут быть равными, и поэтому могут давать неожиданные результаты. Для равных элементов нужно возвращать 0. –

+0

Спасибо за объяснение – knowbody

+0

, если update_at - это время по ISO, это не будет Этот пример предполагает временные метки Unix, но OP опубликовал данные, которые были в формате ISO. Поэтому вам нужно будет преобразовать в временные метки Unix для сравнения. Это можно сделать с помощью 'new Date (iso_str) .getTime()' this will return unix timestamp. –

6

Метод Array.sort() сортирует элементы массива на месте и возвращает массив. Будьте осторожны с Array.sort(), так как это не Immutable. Для неизменного сортировки используйте immutable-sort.

Этот метод предназначен для сортировки массива с использованием текущего updated_at в формате ISO. Мы используем 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()); 

Для ES5:

arr.sort(function(a,b){ 
return new Date(a.updated_at).getTime() - new Date(b.updated_at).getTime(); 
}); 

Если вы измените updated_at быть Unix метки времени вы можете сделать это:

Для ES6:

arr.sort((a,b) => a.updated_at - b.updated_at); 

Для ES5:

arr.sort(function(a,b){ 
return a.updated_at - b.updated_at; 
}); 

Во время этого поста, современные браузеры не поддерживают ES6. Чтобы использовать ES6 в современных браузерах, используйте babel, чтобы перевести код на ES5. Ожидайте поддержку браузера для ES6 в ближайшем будущем.

Array.sort() должен receave возвращаемого значения одного из 3-х возможных исходов:

  • положительного числа (первый пункт> второго элемента)
  • отрицательного числа (первый пункт < второго пункт)
  • 0 если два элемента равны

Обратите внимание, что возвращаемое значение на встроенной функции может быть любым положительным или отрицательным числом. Array.Sort() не волнует, что возвращает номер . Это только заботится, если возвращаемое значение положительное, отрицательное или ноль.

Для неизменяемых вида: (пример ES6)

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); 

Импорт-с вы видите новый способ включить JavaScript в ES6 и делает ваш код очень чистым. Мой личный фаворит.

Неизбежная сортировка не мутирует исходный массив, а возвращает новый массив. Использование const рекомендуется по неизменяемым данным.

1

Еще один, более математический, способ сделать то же самое, но короче:

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); 
}); 

Этот метод может быть выполнен с любым числовым входом

+0

Недостаточный ответ –

+0

Спасибо @ two7s_clash, я очень ценю это !!! –

0
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); 
0

Как This государств ответить в , вы можете использовать Array.sort.

arr.sort(function(a,b){return new Date(a.updated_at) - new Date(b.updated_at)})

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(function(a,b){return new Date(a.updated_at) - new Date(b.updated_at)}); 
 
console.log(arr);

Смежные вопросы