Подтвердить что ты не робот

Сортировка массива Javascript и уникальные

У меня есть такой массив 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?

4b9b3361

Ответ 1

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

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"]

Ответ 2

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

myData.sort().filter(function(el,i,a){if(i==a.indexOf(el))return 1;return 0})

Ответ 3

function sort_unique(arr) {
    return arr.sort().filter(function(el,i,a) {
        return (i==a.indexOf(el));
    });
}

Ответ 4

Здесь мой (более современный) подход с использованием 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])

Ответ 5

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

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

var sortedUnique = f(array);

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

Смотрите live пример

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

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

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

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

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

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

Ответ 6

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

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

Ответ 7

Как насчет:

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

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

Ответ 8

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

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

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

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

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

Ответ 9

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

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

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

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

Ответ 10

Нет избыточного массива "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;
}

Ответ 11

Думаю, я опубликую этот ответ для некоторого разнообразия. Этот метод очистки дубликатов - это то, что я выбрал для проекта во Flash. В настоящее время я работаю примерно месяц назад.

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

var nums = [1, 1, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9, 9, 10];
var newNums = purgeArray(nums);

function purgeArray(ar)
{
    var obj = {};
    var temp = [];
    for(var i=0;i<ar.length;i++)
    {
        obj[ar[i]] = ar[i];
    }
    for (var item in obj)
    {
        temp.push(obj[item]);
    }
    return temp;
}

Там уже 5 других ответов, поэтому я не вижу необходимости публиковать функцию сортировки.

Ответ 12

// Another way, that does not rearrange the original Array 
// and spends a little less time handling duplicates.

function uniqueSort(arr, sortby){
    var A1= arr.slice();
    A1= typeof sortby== 'function'? A1.sort(sortby): A1.sort();

    var last= A1.shift(), next, A2= [last];
    while(A1.length){
        next= A1.shift();
        while(next=== last) next= A1.shift();
        if(next!=undefined){
            A2[A2.length]= next;
            last= next;
        }
    }
    return A2;
}
var myData= ['237','124','255','124','366','255','100','1000'];
uniqueSort(myData,function(a,b){return a-b})

// the ordinary sort() returns the same array as the number sort here,
// but some strings of digits do not sort so nicely numerical.

Ответ 13

Функция sort() только хороша, если ваш номер имеет одну и ту же цифру, например:

var myData = ["3","11","1","2"]

вернется;

var myData = ["1","11","2","3"]

и здесь улучшение функции от mrmonkington

myData.sort().sort(function(a,b){return a - b;}).filter(function(el,i,a){if(i==a.indexOf(el) & el.length>0)return 1;return 0;})

вышеуказанная функция также удалит пустой массив, и вы можете проверить демонстрацию ниже

http://jsbin.com/ahojip/2/edit

Ответ 14

Вот простой лайнер с O(N), предполагающий:

  • вы находитесь в современном браузере или в node.js
  • ваш массив - это строки.

Тогда

> Object.keys([{}].concat(['a', 'b', 'a']).reduce((l,r) => l[r] = l ))
[ 'a', 'b' ]

Объяснение

Исходный набор данных, предположим, что он поступает от внешней функции

let data = ['a', 'b', 'a']

Мы хотим добавить объект к фронту массива

let setup = [{}].concat(data)

Далее мы хотим уменьшить массив до одного значения.

На предыдущем шаге мы добавили объект в массив, чтобы на этом шаге мы могли привязать все значения к этому объекту, как к ключам. Конечным результатом является объект с уникальным набором ключей.

let reduced = setup.reduce((l,r) => l[r] = l)

Мы устанавливаем l[r] = l, потому что в javascript значение выражения присваивания возвращается, когда оператор присваивания используется как выражение.

Далее мы хотим получить ключи этого объекта

let keys = Object.keys(setup)

Какой набор уникальных значений исходного массива

['a', 'b']

Ответ 15

Я боюсь, что вы не можете объединить эти функции, т.е. вы должны сделать что-то вроде этого: -

myData.unique().sort();

В качестве альтернативы вы можете реализовать своего рода sortedset (как доступно на других языках) - который несет как понятие сортировки, так и удаления дубликатов, как вам нужно.

Надеюсь, что это поможет.

Литература: -

Array.sort

Array.unique