在 JavaScript 中连接嵌套数组时测试失败
Tests fail when concatenating nested array in JavaScript
实现了 Radix Sort 对数字列表进行排序。这是我的代码:
function getDigit(number, index, lengthOfLongestNumber) {
let numberString = number.toString();
numberString = numberString.padStart(lengthOfLongestNumber, '0');
return parseInt(numberString[index], 10) || 0;
}
function getLengthOfLongestNumber(numbers) {
// return Math.floor(Math.log10(Math.max(...numbers))) + 1;
let largestNumber = 0;
for (let i = 0; i < numbers.length; i++) {
if (numbers[i] > largestNumber) {
largestNumber = numbers[i];
}
}
return largestNumber.toString().length;
}
function radixSort(numbers) {
const lengthOfLongestNumber = getLengthOfLongestNumber(numbers);
for (let i = lengthOfLongestNumber - 1; i >= 0; i--) {
const buckets = new Array(10).fill().map(() => []);
while (numbers.length) {
const number = numbers.shift();
buckets[getDigit(number, i, lengthOfLongestNumber)].push(number);
}
for (let j = 0; j < 10; j++) {
// numbers = numbers.concat(buckets[j]); ---> uncomment this line and comment out the following while loop
// numbers = [...numbers, ...buckets[j]]; ---> or uncomment this line and comment out the following while loop
while (buckets[j].length) {
numbers.push(buckets[j].shift());
}
}
}
return numbers;
}
当我使用 radixSort
函数中的 concat()
将 buckets
数组合并到 numbers
数组时,测试失败(在内部 for
循环中)。但是如果我改用 while
循环,它会以某种方式通过。
您可以在 CodeSandbox 中查看和 运行 测试。
为什么会这样?它们之间导致测试失败的区别是什么?
对于 returned 数组,使用哪个替代项并不重要,但如果测试希望您对 given 数组,以便在调用后输入数组已排序 本身 ,那么实际上,注释掉的替代方案将不起作用。这是因为这些替代方案 将 分配给 numbers
而不是对其进行变异。
忽略返回的数组时检查备选方案之间的差异,但查看给定的数组:
let arr = [521, 219, 100, 422, 889, 529, 491, 777, 641, 882, 229];
radixSort(arr);
console.log(arr);
注释掉的选项将记录一个空数组。
正确的版本改变了numbers
,并且没有分配一个(新)数组给它。
为了避免循环,你也可以像这样做这个突变:
numbers.push(...buckets[j]);
你甚至可以用这一行来替换围绕该语句的 for
循环:
numbers.push(...buckets.flat());
实现了 Radix Sort 对数字列表进行排序。这是我的代码:
function getDigit(number, index, lengthOfLongestNumber) {
let numberString = number.toString();
numberString = numberString.padStart(lengthOfLongestNumber, '0');
return parseInt(numberString[index], 10) || 0;
}
function getLengthOfLongestNumber(numbers) {
// return Math.floor(Math.log10(Math.max(...numbers))) + 1;
let largestNumber = 0;
for (let i = 0; i < numbers.length; i++) {
if (numbers[i] > largestNumber) {
largestNumber = numbers[i];
}
}
return largestNumber.toString().length;
}
function radixSort(numbers) {
const lengthOfLongestNumber = getLengthOfLongestNumber(numbers);
for (let i = lengthOfLongestNumber - 1; i >= 0; i--) {
const buckets = new Array(10).fill().map(() => []);
while (numbers.length) {
const number = numbers.shift();
buckets[getDigit(number, i, lengthOfLongestNumber)].push(number);
}
for (let j = 0; j < 10; j++) {
// numbers = numbers.concat(buckets[j]); ---> uncomment this line and comment out the following while loop
// numbers = [...numbers, ...buckets[j]]; ---> or uncomment this line and comment out the following while loop
while (buckets[j].length) {
numbers.push(buckets[j].shift());
}
}
}
return numbers;
}
当我使用 radixSort
函数中的 concat()
将 buckets
数组合并到 numbers
数组时,测试失败(在内部 for
循环中)。但是如果我改用 while
循环,它会以某种方式通过。
您可以在 CodeSandbox 中查看和 运行 测试。
为什么会这样?它们之间导致测试失败的区别是什么?
对于 returned 数组,使用哪个替代项并不重要,但如果测试希望您对 given 数组,以便在调用后输入数组已排序 本身 ,那么实际上,注释掉的替代方案将不起作用。这是因为这些替代方案 将 分配给 numbers
而不是对其进行变异。
忽略返回的数组时检查备选方案之间的差异,但查看给定的数组:
let arr = [521, 219, 100, 422, 889, 529, 491, 777, 641, 882, 229];
radixSort(arr);
console.log(arr);
注释掉的选项将记录一个空数组。
正确的版本改变了numbers
,并且没有分配一个(新)数组给它。
为了避免循环,你也可以像这样做这个突变:
numbers.push(...buckets[j]);
你甚至可以用这一行来替换围绕该语句的 for
循环:
numbers.push(...buckets.flat());