2014-09-16 14 views
4

Я относительно новичок в underscore.js, и у меня есть объект, входящий в сервис REST, который выглядит так (я набрал его вручную и назначил его здесь var) :Underscore.js преобразовать объект в массив

var production = [ 
    {key: ["wind", "1"], value: 5}, 
    {key: ["wind", "2"], value: 9}, 
    {key: ["wind", "3"], value: 11}, 
    {key: ["wind", "4"], value: 7}, 
    {key: ["solar", "1"], value: 1}, 
    {key: ["solar", "2"], value: 1}, 
    {key: ["solar", "3"], value: 2}, 
    {key: ["solar", "4"], value: 3}, 
    {key: ["oil", "1"], value: 15}, 
    {key: ["oil", "2"], value: 16}, 
    {key: ["oil", "3"], value: 22}, 
    {key: ["oil", "4"], value: 23}, 
]; 

Потом дальше, у меня есть некоторый код, который разбирает этот объект и создает массивы для элементов, как так:

var orderedProduction = _.chain(production) 
     .groupBy(function (entity) { 
      return entity.key[0]; 
     }) 
     .map(function (values) { 
      return _.map(values, function (entity2) { 
        return entity2.value; 
      }); 
     }) 
     .value(); 

Это дает следующие результаты:

orderedProduction = [ 
    [5, 9, 11, 7], 
    [1, 1, 2, 3], 
    [15, 16, 22, 23] 
] 

Который теряет ключи (ветер/солнце/масло). И используется для рисования графика. Я в дальнейшем иметь возможность проверить, если некоторые из этих массивов отвечают определенный порог, как так:

var threshold = _.map(orderedProduction , function(arr) { 
    return _.max(arr) > 10; 
}); 

Мои требования теперь изменились, и теперь мне нужно, чтобы отфильтровать эти массивы по своей общей сумме, сохраняя при этом ключе.

То, что я хотел бы в конечном итоге с объектом, как так:

orderedProduction = { 
     "wind": [5, 9, 11, 7], 
     "solar": [1, 1, 2, 3], 
     "oil": [15, 16, 22, 23] 
    } 

Было бы здорово, если исправление включено способ просуммировать значения массива и удалить те, которые не могут составить до до определенной суммы. (т. е. исключить солнечную энергию, если она не составляет до 10).

Вот jsfiddle я создал, чтобы испытать все это на: http://jsfiddle.net/2mfjw3jk/


UPDATE: Решение, которое я довольствовалась был такой:

var orderedProduction = _.chain(production) 
    .groupBy(function (entity) { 
     return entity.key[0]; 
    }) 
    .map(function (vals, key) { 
     return [key, _.pluck(vals, 'value')] 
    }) 
    .filter(function(arr) { 
     var sum = 0; 
     _.each(arr[1], function(num){ 
      sum += num; 
     }) 
     return sum > 10; 
    }) 
    .object() 
    .value(); 

Он также фильтрует значений при помощи предопределенный порог (в данном случае - 10).

ответ

6

Вы почти там:

var orderedProduction = _.chain(production) 
    .groupBy(function (entity) { 
     return entity.key[0]; 
    }) 
    .map(function (vals, key) { 
     return [key, _.pluck(vals, 'value')] 
    }) 
    .object() 
    .value(); 

возвращает

{ wind: [ 5, 9, 11, 7 ], 
    solar: [ 1, 1, 2, 3 ], 
    oil: [ 15, 16, 22, 23 ] } 
+0

Awesome. Я справился с этим, используя цепочку, pluck, uniq, object. Но это решение настолько аккуратно. Огромное спасибо. – Husman

2

Вы можете просто использовать функцию map(), предоставляемую в javascript. Указанный _Map() для обратной совместимости. В любом случае, вот код:

var obj = {}; 
production.map(function(data) { 
    if(data.key[0] in obj) { 
     obj[data.key[0]] += data.value; 
    } else { 
     obj[data.key[0]] = 0; 
     obj[data.key[0]] += data.value; 
    } 
}); 
console.log(obj); 

Так что же является то, что петли Повсеместно массива производства. Там он проверяет, находится ли ключ (например, «ключ») в объекте obj или нет. Если он есть, то он просто увеличивает его значение или создает новый ключ и назначает его 0, а затем увеличивает его.

Не самый оптимизированный код, но он работает красиво.

+0

Это полезно, но мне не нужно итогов. Мне все еще нужен массив значений (например, «масло»: [15, 16, 22, 23]) – Husman

1

Это, вероятно, не самый эффективный код, но он выполняет свою работу с использованием подчеркивания.

Live Demo

var production = [ 
    {key: ["wind", "1"], value: 5}, 
    {key: ["wind", "2"], value: 9}, 
    {key: ["wind", "3"], value: 11}, 
    {key: ["wind", "4"], value: 7}, 
    {key: ["solar", "1"], value: 1}, 
    {key: ["solar", "2"], value: 1}, 
    {key: ["solar", "3"], value: 2}, 
    {key: ["solar", "4"], value: 3}, 
    {key: ["oil", "1"], value: 15}, 
    {key: ["oil", "2"], value: 16}, 
    {key: ["oil", "3"], value: 22}, 
    {key: ["oil", "4"], value: 23} 
]; 

var orderedProduction = _.chain(production) 
    .groupBy(function (entity) { 
     return entity.key[0]; 
    }) 
    .map(function(items, key){ 
     var returnVal = [key]; 
     var total = 0; 
     returnVal.push(_.map(items, function(obj){ 
      total += obj.value; 
      return obj.value; 
     })); 

     if(total > 10){ 
      return returnVal; 
     } 

    }) 
    .filter(function(num) { 
     return num !== undefined; 
    }) 
    .object() 
    .value(); 

console.log(production); 
console.log(orderedProduction); 
+0

Это довольно близко. Он дает массив объектов и удаляет солнечный объект. То, что я хотел, было объектом со свойствами (ветер/солнце/масло), и каждое свойство имеет массив чисел. – Husman

+0

Ahh, не уверен, как я пропустил это. Я знаю, что у тебя уже есть ответ, но я все равно исправил это. –

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