2016-04-05 6 views
-5

Предположим, что у меня есть массив следующим образомЯ хочу, чтобы отсортировать элементы массива

var array=[3,4,5,5,5,6,8,3,12,1,1,1]; 

Тогда результат должен быть

array=[5,1,3,4,6,8,12]; 

Обязательное внедрение в JavaScript или nodejs

+3

вы пытались что-нибудь? – JordanHendrix

+1

Пожалуйста, [добавьте код, который вы написали] (https://stackoverflow.com/help/mcve) и проблема, с которой вы столкнулись. SO не пишет для вас код. – Andy

ответ

2

Вот один из способов для этого: JSBIN: https://jsbin.com/josuwir/1/edit?js,console

var array=[3,4,5,5,5,6,8,3,12,1,1,1]; 

var c = array.reduce(function(a, b) { 
    a[b] = ++a[b] || 1; 
    return a; 
}, {}); 


var keys = Object.keys(c); 


var nn = keys.sort(function(a, b) { 
    if (c[a] < c[b]) { 
    return 1; 
    } else { 
    return -1; 
    } 
}).map(function(a) {return Number(a)}); 
3

я использовал комбинацию lodash и простых методов JavaScript массива в этом jsbin example:

var arr = [3,4,5,5,5,6,8,3,12,1,1,1]; 

var sorted = _.sortBy(_.toPairs(arr.reduce(function(agg, curr) { 
    agg[curr] = agg[curr] ? agg[curr] + 1 : 1; 

    return agg; 
}, {})), function(pair) { 
    return -pair[1]; 
}).map(function(pair) { 
    return pair[0]; 
}); 

console.log(sorted); // => ["1", "5", "3", "4", "6", "8", "12"] 

Однако упорядочение "5" и "1" отличается, что упорядочение 3,4,6,8,12, поскольку порядок сортировки не указан для чисел, имеющих одинаковые значения.

Вышеприведенный делает создается карта number=>count (например { "1": 3, "5": 3 }), а затем пары их в качестве кортежей (поскольку объекты не могут быть отсортированы детерминировано в JavaScript: [["1", 3], ["5", 3]]). Затем мы просто сортируем коллекцию кортежей на основе подсчета и сопоставляем по набору кортежей, чтобы вернуть только число (например, ["1", "5", /* etc. */ ]).

1
function sortArray(array) { 

    var reducedArray = array.filter(function(item, pos) { //A copy without duplicates 
     return array.indexOf(item) == pos; 
    }) 

    var elementFreq = {} //Object that contains element frequencies 
    for (var i=0; i<reducedArray.length; i++) { 
     var count = 0; 
     for (var j=0; j<array.length; j++) { 
      if (array[j] == reducedArray[i]) { 
       count++; 
      } 
     } 
     elementFreq[array[i]] = count; 
    } 

    function compare(a,b) { //compares the frequency of two elements 
     return elementFreq[b]-elementFreq[a] 
    } 

    reducedArray.sort(compare) //sorts reducedArray based using compare function 

    return reducedArray 
} 
+0

Это понятный код, но излишне неэффективный. Вы не хотите, чтобы я работал над всем массивом каждый раз, когда вы сравниваете два элемента, это точно. – Harangue

+0

@Harangue Вы правы, спасибо за отзывы. Я редактировал свой код для хранения частот элементов перед сравнением. – digglemister

3

var array = [3, 4, 5, 5, 5, 6, 8, 3, 12, 1, 1, 1]; 
 

 
var obj = {}; 
 

 
array.forEach(e => obj[e] = obj[e] + 1 || 1); 
 

 
var sorted = Object.keys(obj) 
 
    .map(e => ({ n: e, times: obj[e] })) 
 
    .sort((a, b) => b.times - a.times) 
 
    .map(e => e.n); 
 

 
document.write(sorted);

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