我有一个数字数组。我想按顺序排列数字,并在同一数组(数组中的数组)中创建重复的新数组。有人可以帮我一步一步。我真的很想了解
let arr = [1, 2, 4, 591, 392, 391, 2, 5, 10, 2, 1, 1, 1, 20, 20];
// I want to create this [[1,1,1,1],[2,2,2], 4,5,10,[20,20], 391, 392,591]
const sortArray = arr.sort(function(a, b) {
return a - b;
});
答案 0 :(得分:5)
您可以使用Set
提取唯一值,然后对其进行排序(因为对数组数组进行排序比较复杂),然后使用array.reduce
获取原始数组中的所有项目并按唯一的值(如果唯一),否则为值的数组(不确定为什么需要它,但是仍然..)
更多文档参考:
下面的工作代码:
let arr = [1, 2, 4, 591, 392, 391, 2, 5, 10, 2, 1, 1, 1, 20, 20];
// I want to create this [[1,1,1,1],[2,2,2], 4,5,10,[20,20], 391, 392,591]
console.log([...new Set(arr)].sort((a,b) => a - b).reduce((accumulator, next) => {
const filtered = arr.filter(i => i === next);
return accumulator.push(filtered.length === 1 ? filtered[0] : filtered), accumulator
}, []));
答案 1 :(得分:1)
您可以对数组进行排序,并查看最后两个项目和实际项目。
[ 1, 1, 1, 1, 2, 2, 2, 4, 5, 10, 20, 20, 391, 392, 591] array a b c variables ^ actual item
然后检查最后一项b
和实际项目c
是否不相等,并返回包含旧项目和实际项目的新数组。
如果最后一个项目a
之前的项目与实际项目不相等,则它应该是结果集中最后一个项目和实际项目的数组。
否则将实际项目推送到结果集的嵌套最后一个数组中。
var array = [1, 2, 4, 591, 392, 391, 2, 5, 10, 2, 1, 1, 1, 20, 20],
result = array
.sort((a, b) => a - b)
.reduce((r, c, i, { [i - 2]: a, [i - 1]: b }) => {
if (b !== c) return [...r, c];
if (a !== c) return r.pop(), [...r, [b, c]];
r[r.length - 1].push(c);
return r;
}, []);
console.log(result);
答案 2 :(得分:0)
尽管还有其他方法,但是每当我需要以这种方式解析数组的唯一值时,我都会创建一个对象,该对象的属性代表数组值的分组
{ 1: [1, 1, 1], 2: [2 , 2, 2], 4: [4], 5: [5] ...}
然后,您可以根据需要使用本机对象方法来获取对象的所有键或值(或者,如果最终目标不同,则可以使用需要的对象)
Object.keys(obj)
// or
Object.values(obj)
对于您的情况,看起来像
const arr = [1, 2, 4, 591, 392, 391, 2, 5, 10, 2, 1, 1, 1, 20, 20];
const obj = arr.reduce((accum, val) => {
accum[val] = accum[val] || [];
accum[val].push(val);
return accum;
}, {});
const finalArr = Object.values(obj).map(val => val.length > 1 ? val : val[0]);
console.log(finalArr);
答案 3 :(得分:0)
您可以先使用reduce
,然后再使用Array.fill
。在这里reduce将创建一个像这样的对象
{
"1": 4,
"2": 3,
"4": 1,
"5": 1,
"10": 1,
"20": 2,
"391": 1,
"392": 1,
"591": 1
}
表示4
1s
,3
2s
,依此类推。然后,您可以在迭代此对象后使用数组填充。数组fill
的语法为arr.fill(value[, start[, end]])
因此,在我们的情况下,我们将假设new Array(k[keys]).fill(+keys, 0, k[keys])
正在创建一个长度为4
,3
的新数组,以此类推,除了1
之外,从第0个索引开始填充钥匙
let arr = [1, 2, 4, 591, 392, 391,1, 2, 5, 10, 2, 1, 1, 1, 20, 20];
let k = arr.reduce(function(acc, curr) {
if (curr in acc) {
acc[curr] += 1;
} else {
acc[curr] = 1
}
return acc;
}, {});
let grouped = [];
for (let keys in k) {
if (k[keys] !== 1) {
grouped.push(new Array(k[keys]).fill(+keys, 0))
} else {
grouped.push(+keys)
}
}
console.log(grouped)
答案 4 :(得分:0)
您可以计算发生的次数,然后使用该对象创建最终数组。
const arr = [1, 2, 4, 591, 392, 391, 2, 5, 10, 2, 1, 1, 1, 20, 20];
const count = arr.reduce((acc, val) => {
acc[val] = acc[val] + 1 || 1;
return acc;
}, {});
const result = Object
.keys(count)
.sort((a, b) => a - b)
.map((key) => count[key] === 1 ? +key : Array.from({ length: count[key] }).fill(+key));
console.log(result);
答案 5 :(得分:0)
您可以通过多种方式执行此操作。但是,如果要以最佳方式实现,则必须避免 n个正方形循环。
因此可以创建一个值计数字典。并按排序顺序遍历对象的键。
使用Array.reduce
创建数组元素数量的对象。和Array.fill
来过滤具有相同值的数组。
//Given Array
const arr = [1, 2, 4, 591, 392, 391, 2, 5, 10, 2, 1, 1, 1, 20, 20];
//Dictionary with count of each values in array
const arrCountObj = arr.reduce((acc, el) => {
if (acc[el]) {
acc[el] += 1
} else {
acc[el] = 1
}
return acc
}, {})
console.log(arrCountObj)
//Looping over sorted dictionary keys to create array based on condition
var out = Object.keys(arrCountObj).sort((a, b) => a - b).map(x => arrCountObj[x] > 1 ? new Array(arrCountObj[x]).fill(+x) : arrCountObj[x])
console.log(out)
时间复杂度:O(nlogn)
答案 6 :(得分:0)
您可以:
1)遍历数组以构建数字的频率图
2)抓住并按升序对频率映射键进行排序
3)根据频率图中的信息构建一个新的阵列
const arr = [1, 2, 4, 591, 392, 391, 2, 5, 10, 2, 1, 1, 1, 20, 20];
const obj = arr.reduce((acc, c) => {
return acc[c] = (acc[c] || 0) + 1, acc;
}, {});
// {"1":4,"2":3,"4":1,"5":1,"10":1,"20":2,"391":1,"392":1,"591":1}
const keys = Object.keys(obj).sort((a, b) => a - b).map(Number);
// [1,2,4,5,10,20,391,392,591]
const out = keys.map((key) => {
return obj[key] > 1 ? Array(obj[key]).fill(key) : key;
});
// [[1,1,1,1],[2,2,2],4,5,10,[20,20],391,392,591]
console.log(JSON.stringify(out));