2016-11-09 54 views
2

相當複雜的解釋,所以我會盡量明確。Javascript:爲不同大小的數組添加0值

我有一個對象,數據,這是對象的數組,其包括對象的數組和串:

var groups = [ 
    { 
     bars: [ 
      {label: 'a', value: 28}, 
      {label: 'c', value: 16} 
     ], 
     string: 'one' 
    }, 
    { 
     bars: [ 
      {label: 'a', value: 3}, 
      {label: 'b', value: 17}, 
      {label: 'c', value: 24} 
     ], 
     string: 'two' 
    }, 
    { 
     bars: [ 
      {label: 'a', value: 12}, 
      {label: 'd', value: 7}, 
      {label: 'e', value: 36} 
     ], 
     string: 'three' 
    }, 
    { 
     bars: [ 
      {label: 'c', value: 32}, 
      {label: 'e', value: 2} 
     ], 
     string: 'four' 
    } 
] 

我需要所有「杆」的對象是相同的大小,並且具有0如果所述標籤的對象不存在,則返回值。正如您所看到的,與「bars」關聯的標籤鍵是一個有限列表。我的主要問題是「組」對象的大小以及「條」對象的大小是動態的。隨着下劃線,我已經使用:

var labelNames = _.uniq(_.flatten 
    (_.map(data.groups,function(groups) { 
    return _.pluck(groups.bars, 'label'); 
}))); 

提取已知標籤列表給我

['a', 'b', 'c', 'd', 'e'] 

現在我要地圖這個數組的酒吧對象給我這樣的輸出:

var groups = [ 
    { 
     bars: [ 
      {label: 'a', value: 28}, 
      {label: 'b', value: 0}, 
      {label: 'c', value: 16}, 
      {label: 'd', value: 0}, 
      {label: 'e', value: 0} 
     ], 
     string: 'one' 
    }, 
    { 
     bars: [ 
      {label: 'a', value: 3}, 
      {label: 'b', value: 17}, 
      {label: 'c', value: 24}, 
      {label: 'd', value: 0}, 
      {label: 'e', value: 0} 
     ], 
     string: 'two' 
    }, 
    { 
     bars: [ 
      {label: 'a', value: 12}, 
      {label: 'b', value: 0}, 
      {label: 'c', value: 0}, 
      {label: 'd', value: 7}, 
      {label: 'e', value: 36} 
     ], 
     string: 'three' 
    }, 
    { 
     bars: [ 
      {label: 'a', value: 0}, 
      {label: 'b', value: 0}, 
      {label: 'c', value: 32}, 
      {label: 'd', value: 0}, 
      {label: 'e', value: 2} 
     ], 
     string: 'four' 
    } 
] 

如果有幫助,我必須有酒吧,因爲我已經創建了一個包含這些對象的高分辨率系列like this example。 我希望這是有道理的。任何幫助,將不勝感激。試圖弄清楚這一點我一直在瘋狂。

+2

用'_.each'遍歷'groups'的每個元素。使用'_.pluck'來獲取'bars'的所有標籤,以及'_.difference'和已知標籤之間的'_.difference'以獲得缺失的標籤。然後添加具有這些標籤和「value:0」的元素。 – Barmar

+0

謝謝!這讓我大部分時間都在那裏,所以我將它發佈爲答案 – bspckl

回答

3

這是我爲那些誰在這個蹣跚走去。

_.each(data.groups, function(group) { 
    var currentValues = _.pluck(group.bars, 'label'); 
    var zeroValues = _.difference(labelNames, currentValues); 
    _.each(zeroValues, function(newLabel) { 
     group.bars.push({label: newLabel, value: 0}); 
    }); 
}); 
+1

非常好,真正展現了underscore.js的強大功能。 – Barmar

1

這應該做的伎倆:

// First, iterate over each group 
for (var i = 0; i < groups.length; i++) { 

    var bars = groups[i].bars; 

    // Second, iterate over each of the previously collected labels, e.g. var labels = ['a', 'b', 'c', 'd', 'e'] 
    for (var j = 0; j < labels.length; j++) { 

     // Assume label does not exist, until proven otherwise 
     var labelDoesNotExist = true; 

     // Third, iterate over the bars' existing labels 
     for (var k = 0; k < bars.length; k++) { 

      var label = bars[k].label; 

      // Check if the label matches the current iteration of pre-collected labels 
      if (label == labels[j]) { 
       labelDoesNotExist = false; 
      } 
     } 

     // If no existing label matches any of the pre-collected labels, then create a new label with value of 0 
     if (labelDoesNotExist) { 
      bars.push({ 
       'label': labels[j], 
       'value': '0' 
      }); 
     } 
    } 
} 
1

的功能和EcmaScript6替代:

首先,獲取標籤:[ 'A',「B, 'C',...]

let labels = groups 
    .reduce((res, item) => 
    [...res, ...item.bars.map(b => b.label)], 
    []) 
    .filter((value, index, self) => 
    self.indexOf(value) === index 
) 
    .sort() 

使用reduce和concat節省一天!

,二步,讓工作而無需供應商庫:

let newgroups = groups.map(item => 
    Object.assign({}, item, {bars : [ 
    ...item.bars, 
    ...labels.filter(l => 
     !item.bars.some(b => b.label == l) 
    ) 
     .map(l => ({label:l, value:0})) 
    ].sort((a, b) => a.label < b.label ? -1:1)}) 
); 

最後sort是opcional,但酒吧itens可以與這更好。

適用於Chrome和實際引擎,無需編譯。 ES6是生命

+0

更具可讀性的替代方法https://gist.github.com/AbraaoAlves/e1ed0cc21eca5750fa80610e3674bd05 –