2016-02-29 77 views
2

我不確定這是否是正確的方法,但我很好奇它是否可以完成。我有一個對象,我需要創建一個數組,鍵是項目,值id是它在數組中重複的次數。使用擴展運算符在使用映射時擴展數組

const arrayInstructions = { 
    'm': 5, 
    's': 5, 
    'p': 5 
} 

這將使['m','m','m','m','m','s','s' ... ]

這是工作方法:

var array = [] 
Object.keys(arrayInstructions).forEach(function (agenda) { 
    array = array.concat(_.fill(Array(arrayInstructions[agenda]), agenda)) 
}) 

能把它以這種方式來完成:

var deck = Object.keys(streamDeck).map(function (agenda) { 
    var partial = _.fill(Array(streamDeck[agenda]), agenda) 
    return ...partial // I know this is wrong 
}) 
+1

不,不能。你正在尋找'concatMap'(JS沒有)。 – Bergi

+0

考慮Object.keys(obj).reduce((s,k)=> s + k.repeat(obj [k]),'').split('')'。它無用的字符串連接,但它很短。 – Oriol

回答

0

你可以使用傳播上Array.prototype.concat生成最終陣列:

const arrayInstructions = { 'm': 5, 's': 5, 'p': 5 }; 
 

 
// This works because Array.prototype behaves like an empty list here 
 
const deck = Array.prototype.concat(
 
    ..._.map(arrayInstructions, (times,agenda) => _.times(times, _=>agenda)) 
 
); 
 

 
log(JSON.stringify(deck)); 
 

 
function log(x) { document.getElementsByTagName('pre')[0].appendChild(document.createTextNode(x)); }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.5.1/lodash.js"></script> 
 
<pre></pre>

UPDATE

考慮BERGI的建議,這個版本更短,並且不依賴關於數組上下文中Array.prototype的行爲:

const deck = [].concat(..._.map(arrayInstructions, 
    (times,agenda) => _.times(times, _=>agenda) 
)); 
+0

我會推薦'[] .concat(... ...)'雖然 – Bergi

+0

@Bergi我也在考慮,以某種方式''.concat(... x)'感覺更健壯。你知道'Array.prototype.concat(... x)'不能工作的具體場景嗎? –

+0

'Array.prototype [0] =「gotcha」'將會是災難性的:-)不可否認,它有點做作,但如果有人以類似的方式使用'Array.prototype.push(...)'會發生。 – Bergi

0

有沒有很好的理由來使用這裏傳播運營商?

在它最簡單的形式,傳播經營者,您可以使用一個數組,其中多個「元素」或參數預期,爲您例如像

var part = [2, 3]; 
var arr = [1, ...part, 4]; // [1,2,3,4] 

這似乎是有用的,但你填充陣列和連接在一起,並使用concat似乎更合適,但是如果你使用apply你可以限制這一個單一的呼叫concat並返回地圖

"use strict" 
 

 
const arrayInstructions = { 
 
    'm': 5, 
 
    's': 1, 
 
    'p': 2 
 
} 
 

 
var deck = [].concat.apply([], Object.keys(arrayInstructions).map(function(k) { 
 
    return new Array(arrayInstructions[k]).fill(k) 
 
})); 
 

 

 
//output 
 
document.body.innerHTML = '<pre>' + JSON.stringify(deck, 0, 4) + '</pre>';

0

由於Bergisaid JS沒有concatMap,但用戶可以自行定義此功能:

function concatMap(array, func, thisArg) { 
    return [].concat.apply([], [].map.call(array, func, thisArg)); 
} 
concatMap(
    Object.keys(arrayInstructions), 
    k => new Array(arrayInstructions[k]).fill(k) 
);