使用 map 时使用扩展运算符扩展数组
Using spread operator to extend array when using map
我不确定这是否是正确的方法,但我很好奇是否可以这样做。我有一个对象,我需要从中创建一个数组,键是项目,值 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
})
这里没有充分的理由使用展开运算符?
在最简单的形式中,展开运算符允许您使用一个数组,其中需要多个 "elements" 或参数,例如
var part = [2, 3];
var arr = [1, ...part, 4]; // [1,2,3,4]
这看起来确实很有用,但是你正在填充数组并将它们连接在一起,使用 concat
似乎更合适,但是你可以将它限制为一次调用 concat
如果你使用apply
和 return 一张地图
"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>';
您可以在 Array.prototype.concat
上使用 spread 来构建最终数组:
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>
更新
考虑到 Bergi 的建议,此版本较短且不依赖数组上下文中 Array.prototype
的行为:
const deck = [].concat(..._.map(arrayInstructions,
(times,agenda) => _.times(times, _=>agenda)
));
因为Bergi 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)
);
我不确定这是否是正确的方法,但我很好奇是否可以这样做。我有一个对象,我需要从中创建一个数组,键是项目,值 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
})
这里没有充分的理由使用展开运算符?
在最简单的形式中,展开运算符允许您使用一个数组,其中需要多个 "elements" 或参数,例如
var part = [2, 3];
var arr = [1, ...part, 4]; // [1,2,3,4]
这看起来确实很有用,但是你正在填充数组并将它们连接在一起,使用 concat
似乎更合适,但是你可以将它限制为一次调用 concat
如果你使用apply
和 return 一张地图
"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>';
您可以在 Array.prototype.concat
上使用 spread 来构建最终数组:
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>
更新
考虑到 Bergi 的建议,此版本较短且不依赖数组上下文中 Array.prototype
的行为:
const deck = [].concat(..._.map(arrayInstructions,
(times,agenda) => _.times(times, _=>agenda)
));
因为Bergi 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)
);