使用扩展运算符在使用map时扩展数组

4

我不确定这是否是正确的方法,但我很好奇它是否可以实现。我有一个对象,需要创建一个数组,其中键是项,值是它在数组中重复的次数。

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
иҖғиҷ‘дҪҝз”Ё Object.keys(obj).reduce((s,k) => s+k.repeat(obj[k]), '').split('')гҖӮе®ғдјҡиҝӣиЎҢж— з”Ёзҡ„еӯ—з¬ҰдёІжӢјжҺҘпјҢдҪҶеҫҲз®ҖзҹӯгҖӮ - Oriol
3个回答

2

这里没有使用展开运算符的充分理由吗?

最简单的形式下,展开运算符可以让你在期望多个“元素”或参数的地方使用数组,例如:

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>';


2
你可以在 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>

更新

考虑到Bergi的建议,这个版本更短,并且不依赖于数组上下文中Array.prototype的行为:

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

我建议使用 [].concat(... …) - Bergi
@Bergi 我也在考虑这个问题,不过 [].concat(...x) 似乎更加健壮。你知道有哪些具体的情况 Array.prototype.concat(...x) 不能胜任吗? - Tamas Hegedus
Array.prototype[0] = "gotcha"会是灾难性的 :-) 虽然有点牵强,但如果有人以类似的方式使用Array.prototype.push(…),这种情况可能发生。 - Bergi

0

正如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)
);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接