从具有多个副本的对象创建数组的最佳方法
Best way to create an array from an object that has number of copies
来自这样的对象:
{a:1, b: 2, c: 3}
我想变成
['a', 'b', 'b', 'c', 'c', 'c']
其中键是字符串,值是份数,顺序无关紧要。
最好的方法是什么?
我正在考虑使用 array.fill,但不确定这是否真的比迭代和推送更容易。
编辑:目前是这样的:
const arr = []
_.each(obj, function (v, k) {
_.times(v, function () {
arr.push(k)
})
})
您可以 flatMap
the Object.entries
and fill
每个大小的数组。
const obj = { a: 1, b: 2, c: 3 };
const result = Object.entries(obj).flatMap(([k, v]) => Array(v).fill(k));
console.log(result)
或使用 Lodash
const obj = { a: 1, b: 2, c: 3 };
const arr = _.flatMap(obj, (v,k) => Array(v).fill(k))
console.log(arr);
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
但没有什么比简单的循环更好的了
const obj = { a: 1, b: 2, c: 3 };
const result = []
for (let [k, v] of Object.entries(obj)) {
while (v--) {
result.push(k)
}
}
console.log(result)
您可以使用 Object.entries
和 Array#reduce
如下:
const input = {a:1, b: 2, c: 3};
const output = Object.entries(input).reduce(
(prev, [key,value]) => prev.concat( Array(value).fill(key) ),
[]
);
console.log( output );
或者,使用 Array#push
而不是 Array#concat
,
const input = {a:1, b: 2, c: 3};
const output = Object.entries(input).reduce(
(prev, [key,value]) => prev.push( ...Array(value).fill(key) ) && prev,
[]
);
console.log( output );
或者,使用 for
循环,
const input = {a:1, b: 2, c: 3};
const output = [],
pairs = Object.entries(input);
for(let i = 0; i < pairs.length; i++) {
const [key, value] = pairs[i];
for(let j = 0; j < value; j++) {
output.push( key );
}
}
console.log( output );
我会使用 Object.keys
将对象转换为键数组,然后使用新创建的空结果数组,然后通过键进行映射。
对于每个键,我都会向现有结果添加一个填充数组。
这是针对该问题的 ES6 解决方案(不需要额外的库)
const obj = { a: 1, b: 2, c: 3 };
let result = []
Object.keys(obj).forEach(key => {
result = [...result, ...new Array(obj[key]).fill(key)]
})
console.log(result)
来自这样的对象:
{a:1, b: 2, c: 3}
我想变成
['a', 'b', 'b', 'c', 'c', 'c']
其中键是字符串,值是份数,顺序无关紧要。
最好的方法是什么?
我正在考虑使用 array.fill,但不确定这是否真的比迭代和推送更容易。
编辑:目前是这样的:
const arr = []
_.each(obj, function (v, k) {
_.times(v, function () {
arr.push(k)
})
})
您可以 flatMap
the Object.entries
and fill
每个大小的数组。
const obj = { a: 1, b: 2, c: 3 };
const result = Object.entries(obj).flatMap(([k, v]) => Array(v).fill(k));
console.log(result)
或使用 Lodash
const obj = { a: 1, b: 2, c: 3 };
const arr = _.flatMap(obj, (v,k) => Array(v).fill(k))
console.log(arr);
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
但没有什么比简单的循环更好的了
const obj = { a: 1, b: 2, c: 3 };
const result = []
for (let [k, v] of Object.entries(obj)) {
while (v--) {
result.push(k)
}
}
console.log(result)
您可以使用 Object.entries
和 Array#reduce
如下:
const input = {a:1, b: 2, c: 3};
const output = Object.entries(input).reduce(
(prev, [key,value]) => prev.concat( Array(value).fill(key) ),
[]
);
console.log( output );
或者,使用 Array#push
而不是 Array#concat
,
const input = {a:1, b: 2, c: 3};
const output = Object.entries(input).reduce(
(prev, [key,value]) => prev.push( ...Array(value).fill(key) ) && prev,
[]
);
console.log( output );
或者,使用 for
循环,
const input = {a:1, b: 2, c: 3};
const output = [],
pairs = Object.entries(input);
for(let i = 0; i < pairs.length; i++) {
const [key, value] = pairs[i];
for(let j = 0; j < value; j++) {
output.push( key );
}
}
console.log( output );
我会使用 Object.keys
将对象转换为键数组,然后使用新创建的空结果数组,然后通过键进行映射。
对于每个键,我都会向现有结果添加一个填充数组。
这是针对该问题的 ES6 解决方案(不需要额外的库)
const obj = { a: 1, b: 2, c: 3 };
let result = []
Object.keys(obj).forEach(key => {
result = [...result, ...new Array(obj[key]).fill(key)]
})
console.log(result)