[英]Organize duplicates into individual array that is ordered
我有一个带数字的数组。 我想按顺序放置数字,并在同一个数组(数组中的数组)中创建带有重复数据的新数组。 有人可以一步一步帮助我。 我真的很想了解
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; });
您可以使用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, 2, 2, 2, 4, 5, 10, 20, 20, 391, 392, 591] array abc 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);
虽然还有其他方法,每当我需要以这种方式从数组中解析唯一值时,我将创建一个对象的属性表示数组值的分组
{ 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);
您可以使用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)
您可以计算出现次数,然后使用该对象创建最终数组。
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);
你可以用这种方式做这件事。 但是如果你想以最好的方式实现,你必须避免使用n个方形循环 。
因此可以创建值计数字典。 并按排序顺序循环对象的键。
使用Array.reduce
创建数组elemnts的对象。 和Array.fill
来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)
你可以:
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));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.