Сортировка массива Javascript и уникальный - PullRequest
49 голосов
/ 29 января 2011

У меня есть массив JavaScript, подобный этому:

var myData=['237','124','255','124','366','255'];

Мне нужно, чтобы элементы массива были уникальными и отсортированными:

myData[0]='124';
myData[1]='237';
myData[2]='255';
myData[3]='366';

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

var myData[0]=num.toString();
//...and so on.

Есть ли способ выполнить все эти задачи в JavaScript?

Ответы [ 17 ]

130 голосов
/ 29 января 2011

Это на самом деле очень просто.Гораздо проще найти уникальные значения, если значения отсортированы первыми:

function sort_unique(arr) {
  if (arr.length === 0) return arr;
  arr = arr.sort(function (a, b) { return a*1 - b*1; });
  var ret = [arr[0]];
  for (var i = 1; i < arr.length; i++) { //Start loop at 1: arr[0] can never be a duplicate
    if (arr[i-1] !== arr[i]) {
      ret.push(arr[i]);
    }
  }
  return ret;
}
console.log(sort_unique(['237','124','255','124','366','255']));
//["124", "237", "255", "366"]
33 голосов
/ 16 августа 2011

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

myData.sort().filter(function(el,i,a){return i===a.indexOf(el)})
16 голосов
/ 15 января 2013
function sort_unique(arr) {
    return arr.sort().filter(function(el,i,a) {
        return (i==a.indexOf(el));
    });
}
14 голосов
/ 28 февраля 2017

Теперь вы можете получить результат всего за одну строку кода.

Использование new Set для уменьшения массива до уникального набора значений. Примените метод sort после, чтобы упорядочить строковые значения.

var myData=['237','124','255','124','366','255']

var uniqueAndSorted = [...new Set(myData)].sort() 

ОБНОВЛЕНО для более новых методов, введенных в JavaScript со времени вопроса.

13 голосов
/ 10 декабря 2015

Вот мой (более современный) подход, использующий Array.protoype.reduce():

[2, 1, 2, 3].reduce((a, x) => a.includes(x) ? a : [...a, x], []).sort()
// returns [1, 2, 3]

Редактировать: Более производительная версия, как указано в комментариях:

arr.sort().filter((x, i, a) => !i || x != a[i-1])
8 голосов
/ 29 января 2015

Как насчет:

array.sort().filter(function(elem, index, arr) {
  return index == arr.length - 1 || arr[index + 1] != elem
})

Это похоже на ответ @loostro, но вместо использования indexOf, который будет повторять массив для каждого элемента, чтобы убедиться, что он найден первым, он просто проверяет, что следующий элемент отличается от текущего.

6 голосов
/ 29 января 2011

Попробуйте использовать внешнюю библиотеку, например подчеркивание

var f = _.compose(_.uniq, function(array) {
    return _.sortBy(array, _.identity);
});

var sortedUnique = f(array);

Это зависит от _.compose, _.uniq, _.sortBy, _.identity

Смотрите в прямом эфире пример

Что он делает?

Нам нужна функция, которая принимает массив, а затем возвращает отсортированный массив с удаленными неуникальными записями.Эта функция должна выполнять две вещи: сортировать и делать массив уникальным.

Это хорошая работа для компоновки, поэтому мы собираем вместе уникальную функцию & sort._.uniq можно просто применить к массиву с одним аргументом, поэтому он просто передается _.compose

функции _.sortBy требуется условный функционал сортировки.он ожидает функцию, которая возвращает значение, и массив будет отсортирован по этому значению.Поскольку значение, по которому мы упорядочиваем его, является значением в массиве, мы можем просто передать функцию _.identity.

Теперь у нас есть композиция функции (которая принимает массив и возвращает уникальный массив) и функции, которая (принимает массив и возвращает отсортированный массив, отсортированный по их значениям).

Мы просто применяем композицию к массиву и получаем наш уникально отсортированный массив.

5 голосов
/ 08 февраля 2012

Эта функция не работает более чем для двух повторяющихся значений:

function unique(arr) {
    var a = [];
    var l = arr.length;
    for(var i=0; i<l; i++) {
        for(var j=i+1; j<l; j++) {
            // If a[i] is found later in the array
            if (arr[i] === arr[j])
              j = ++i;
        }
        a.push(arr[i]);
    }
    return a;
};
1 голос
/ 27 февраля 2014

Нет избыточного массива "return", нет встроенных ECMA5 (я уверен!) И просто для чтения.

function removeDuplicates(target_array) {
    target_array.sort();
    var i = 0;

    while(i < target_array.length) {
        if(target_array[i] === target_array[i+1]) {
            target_array.splice(i+1,1);
        }
        else {
            i += 1;
        }
    }
    return target_array;
}
1 голос
/ 17 ноября 2012

Способ использования пользовательской функции сортировки

//func has to return 0 in the case in which they are equal
sort_unique = function(arr,func) {
        func = func || function (a, b) {
            return a*1 - b*1;
        };
        arr = arr.sort(func);
        var ret = [arr[0]];
        for (var i = 1; i < arr.length; i++) {
            if (func(arr[i-1],arr[i]) != 0) 
                ret.push(arr[i]);
            }
        }
        return ret;
    }

Пример: порядок удаления для массива объектов

MyArray = sort_unique(MyArray , function(a,b){
            return  b.iterator_internal*1 - a.iterator_internal*1;
        });
...