如何压缩数组以减少其在 Javascript 中的元素数量?



我有一个包含数字的数组,在该数组中,有一些数字以连续顺序一个接一个地出现多次,我想将这些重复的数字压缩成非常特定的格式"Number*Times"以减小数组的大小:

input:  [0, 1, 2, 0, 0, 0, 3, 2, 0, 0, 0, 0, 0, 0, 5, 6, 0]
---------^^^^^^^^^-----^^^^^^^^^^^^^^^^^^^--------
output: [0, 1, 2,'0x3', 3, 2, '0x6', 5, 6, 0]
let array = [0, 1, 2, 0, 0, 0, 3, 2, 0, 0, 0, 0, 0, 0, 5, 6, 0];
let string = array.toString();
let string_compressed = string.replace(/(d+,)(1)+/g, (x) => {
return "Number*" + x.split(",").length + ",";
});
let array_compressed = string_compressed
.split(",")
.map((x) => (isNaN(Number(x)) ? x : Number(x)));
console.log(array_compressed); //[0, 1, 2, 'Number*4', 3, 2, 'Number*7', 5, 6, 0]

我不知道如何获得重复的数字,所以我把数字代替了! 我用正则表达式来解决它,我知道如果你认为用正则表达式解决问题,它们就会变成两个问题!
但是伙计们,我确定这不是解决这个问题的有效方法,还有其他方法可以解决这个问题! 如果你想解决这个问题,你有什么建议?

因为用于查找重复的数字数的正则表达式仅与数组中按连续顺序排列的数字匹配,因此您只需获取x.split(",")数组的第一个索引并返回该索引即可。

编辑:

此外,正如@qrsngky的那样,您的x.split(",").length实际上长度不正确,因为当您用逗号拆分它时,末尾有一个空字符:

let array = [0, 1, 2, 0, 0, 0, 3, 2, 0, 0, 0, 0, 0, 0, 5, 6, 0];
let string = array.toString();
let string_compressed = string.replace(/(d+,)(1)+/g, (x) => {
console.log(x.split(","));
return "Number*" + x.split(",").length + ",";
});
let array_compressed = string_compressed
.split(",")
.map((x) => (isNaN(Number(x)) ? x : Number(x)));
console.log(array_compressed);

很抱歉错过了,并道具评论!我只是通过从长度中减去一个来修复它。

编辑 2:

对于边缘情况,我们可以添加一个逗号并使用切片。

我在下面附上了完整的固定代码片段:

let array = [0, 1, 2, 0, 0, 0, 3, 2, 0, 0, 0, 0, 0, 0, 5, 6, 0, 0, 0];
let string = array.toString() + ",";
let string_compressed = string.replace(/(d+,)(1)+/g, (x) => {
return x.split(",")[0] + "*" + (x.split(",").length - 1) + ",";
});
let array_compressed = string_compressed
.slice(0, -1)
.split(",")
.map((x) => (isNaN(Number(x)) ? x : Number(x)));
console.log(array_compressed);

假设您的原始数组仅由数字组成。

非正则表达式方法:基于 for 循环并计算遇到的重复次数。

let array = [0, 1, 2, 0, 0, 0, 3, 2, 0, 0, 0, 0, 0, 0, 5, 6, 0]
let buffer = [];
let currentNum = array[0], count = 1;
for (let i = 1; i < array.length; i++) {
if (array[i] === currentNum) {
++count;
} else {
buffer.push( count === 1 ? currentNum : (currentNum + 'x' + count) );
currentNum = array[i];
count = 1;
}
}
//don't forget the last number
if(currentNum !== undefined) buffer.push( count === 1 ? currentNum : (currentNum + 'x' + count) );
console.log(buffer);

if(currentNum !== undefined)检查仅在它是空数组的情况下有用。

另一个如何通过编码你想要做的事情来不进行字符串操作的例子:

function packArray(array) {
var packed = [];
for( var i = 0; i < array.length; i=j) {
var entry = array[i];
for(var j = i+1; array[j] === entry && j<array.length; ++j);
packed.push( j > i+1 ? `${entry}x${j-i}` : entry);
}
return packed;
}
console.log( packArray([0, 1, 2, 0, 0, 0, 3, 2, 0, 0, 0, 0, 0, 0, 5, 6, 0]))

您可以用let替换varvar j除外,这些应保持不变以允许访问嵌套for循环之外的j

最新更新