2012-01-05 4 views
1

В настоящее время я довольно новичок в JS и подчеркиваю. Я хочу узнать, какое именно число больше всего встречается в данном массиве (скажем, var a на данный момент). Будучи пользователем avid python, я использую его суммирование в частотном телеграфе, а затем выводя его в кортежи [(1, 3), (2, 2), ...], а затем сортирую его так.Подстрочный график частоты построения Javascript

Каков наилучший способ сделать это в javascript?

function votesTied() { 
    var a = [1, 2, 3, 1, 2, 4, 6, 1, 7]; 
    var tele = {}; 
    _.each(a, function(key) { 
    if (tele[key]) { 
     tele[key]++; 
    } else { 
     tele[key] = 1; 
    } 
    }); 

    var items = _.map(tele, function(frequency,key) { return [key,frequency]; }); 
    var results = _.sortBy(items, function(tuple) { return -1 * tuple[1]; }).value(); 

    return results.length > 1 && results[0][1] == results[1][1]; 
} 

Я спрашиваю, потому что я могу буквально сделать все это в 1 строке питона. Я уверен, что есть более элегантный способ написать это в подчеркивании или javascript.

ответ

1

возможно это?

result = _.chain(a) 
    .groupBy(function(x) { return x }) 
    .map(function(v, k) { return [k, v.length] }) 
    .sortBy(function(x) { return -x[1] }) 
    .value(); 
5

Очень жаль, что подчеркивают «s map() функции не возвращает объект Постояных свойств, потому что позволили бы что-то вроде:

var t = _.chain (a) 
      .groupBy (function (p) { return p; }) 
      .map (function (e) { return _.size (e); }) 
      .value(); 

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

var t = {}; 
_.chain (a) 
    .groupBy (function (p) { return p; }) 
    .each (function (e, i) { 
    t[i] = _.size (e); 
    }); 

Это будет собирать все в t.

UPDATE

Я не мог позволить ей быть, поэтому я проверил источник для подчеркивания «s map() и внесены следующие изменения, чтобы позволить для первого фрагмента кода выше:

_.map = function(obj, iterator, context) { 
    // determine the return type 
    if (_.isArray (obj)) { 
     var results = []; 
    } 
    else { 
     var results = {}; 
    } 
    if (obj == null) return results; 
    // @xxx: we need to override the native map(), thus the next line is commented out 
    // if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context); 
    each(obj, function(value, index, list) { 
     results[index] = iterator.call(context, value, index, list); 
    }); 
    if (obj.length === +obj.length) results.length = obj.length; 
    return results; 
    }; 

Я не проверял это, хотя, но это должно сработать.

1

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

При использовании подчеркивание-х reduce() так:

_.reduce([1, 2, 3, 1, 2, 4, 6, 1, 7], function(frequencies, value) { 
    frequencies[value] = frequencies[value] && frequencies[value] + 1 || 1; 
    return frequencies; 
}, {}); 

Как сказано в документации, первый параметр reduce() является массив, который будет уменьшен, второй обратный вызов сокращение и третий является начальное состояние memo/агрегация - это пустой объект, который мы заполняем частотными данными во время сокращения.

Результат должен выглядеть следующим образом:

{1: 3, 2: 2, 3: 1, 4: 1, 6: 1, 7: 1} 

То есть объект с ключами для каждого уникального элемента и значений с их соответствующей частотой.

Возможно, небольшое уменьшение ясности, но оно достаточно близко к запрошенному однострочному и требует не более, чем подчеркивания запасов.

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