问题描述
我对javascript很陌生,并且我试图构建这个在挑战中发现的功能。我已经设法解决了这个问题,但是我觉得这是一种非常复杂的处理方式,最快的方法是什么?
基本上, answer(数组)应该对此进行转换:
const array = [1,2,4,591,392,391,5,10,1,20,20];
对此:
newArray = [[1,1],[2,2],[20,20],591];
到目前为止,这是我的代码:
const array = [1,20];
const duplicates = arr =>
arr.reduce((a,b) => ({ ...a,[b]: (a[b] || 0) + 1
}),{})
array.sort((a,b) => a - b);
let array1 = duplicates(array);
var values = Object.values(array1);
var keys = Object.keys(array1);
var newArray = [];
for (let i = 0; i < keys.length; i++) {
let tempArray = [];
for (let j = 0; j < values[i]; j++) {
tempArray.push(keys[i]);
}
newArray.push(tempArray);
}
console.log(newArray);
重复功能来自This post about finding duplicate values
解决方法
看看这种单线。猜猜这就是您所需要的。
请注意,这不是实现此目的的最有效方法,但请猜它是美丽的!
const array = [1,2,4,591,392,391,5,10,1,20,20];
const newArray = [...new Set(array)].sort((a,b) => a-b).map(e => new Array(array.filter( i => i === e).length).fill(e)).map(e => e.length === 1 ? e[0] : e);
console.log(newArray);
这是如何工作的:
- 我们正在根据数组创建一个具有唯一值
[...new Set(array)]
的集合
- 我们正在对集合
.sort((a,b) => a-b)
的键进行排序 - 我们正在遍历每个值,并计算该值在数组
.map(e => new Array(array.filter( i => i === e).length);
中的出现 - 在最后一步中,我们用值的数量和来自
.fill(e)
上方集合中的值填充新的Array - 我们正在遍历数组,如果只有单个值
.map(e => e.length === 1 ? e[0] : e)
,则使条目变平坦
您的方法足够好(快速)。我对键使用B
进行了一些修改,以将键从字符串转换回数字。并确保不嵌套单个元素(作为OP中的预期输出。
parseInt()
,
鉴于排序后的数组(升序),您可以有2个变量,一个变量存储元素的排序后唯一数组,一个变量存储数组中元素的出现
此后,您将映射唯一的对象,如果出现次数大于一个,则返回一个数组,该数组由该元素填充并带有该元素出现的长度,否则只需返回该元素
const array = [1,20];
const duplicates = arr =>
arr.reduce((a,b) => ({ ...a,[b]: (a[b] || 0) + 1
}),{})
array.sort((a,b) => a - b);
let array1 = duplicates(array);
var values = Object.values(array1);
var keys = Object.keys(array1);
var newArray = [];
for (let i = 0; i < keys.length; i++) {
let tempArray = [];
if (values[i] === 1) {
newArray.push(parseInt(keys[i]));
} else {
newArray.push(Array(values[i]).fill(parseInt(keys[i])));
}
}
console.log(newArray);
,
您快完成了。但是有一些改进。
const array = [1,20];
array.sort((a,b) => a - b);
let groupedArr = array.reduce((acc,a) => {
acc[a] = acc[a] || [];
acc[a].push(a);
return acc;
},{});
let newArray = [];
for (a in groupedArr) {
if (groupedArr[a].length > 1) {
newArray.push(groupedArr[a]);
} else {
newArray.push(groupedArr[a][0]);
}
}
console.log(newArray);
,
解决方案#1
const array = [1,20];
// [...array] prevents mutation of original array when invoking sort method
const sortedNested = [...array].sort().reduce((acc,cur,idx,org) => {
if (!acc[cur]) {
acc[cur] = cur;
} else if (Array.isArray(acc[cur])) {
acc[cur].push(cur);
} else {
acc[cur] = [cur,cur];
}
return idx === org.length - 1 ? Object.values(acc) : acc;
},{});
console.log(sortedNested);
解决方案2
const array = [1,20];
// get distinct array elements
const distinct = Array.from(new Set(array));
// map to desired output
const nested = distinct.map(value => {
const length = array.filter(_value => _value === value).length;
return length === 1 ? value : Array.from({length}).fill(value);
})
// sort ascending
.sort(
// return a - b; if either a or b is array get their first element
(a,b) => (Array.isArray(a) ? a[0] : a) - (Array.isArray(b) ? b[0] : b)
);
console.log(nested);