从给定数组生成增量值数组
Generate an array of incremental values from a given array
如何从给定数组生成增量值数组
我们的想法是创建一种菱形,阵列在到达阵列中间后开始缩小尺寸。换句话说,最长的数组将是包含数组中间值的数组或 (array.length/2 + 1)
如果元素短而无法在后半部分完成数组,只需将其替换为 'E' 以指示空 space,就像第二个示例一样。
example 1
var array = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p']
//the longest array in length is containing 'i' which is the value at
array.length/2 + 1
var output = [
['a'],
['b','c'],
['d','e','f'],
['g','h','i','j'],
['k','l','m'],
['n','o'],
['p']
]
example 2
var array = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t']
enter code here
//the longest array in length is containing 'k' which is the value at array.length/2 + 1
var output = [
['a'],
['b','c'],
['d','e','f'],
['g','h','i','j'],
['k','l','m','n','o'],
['p','q','r','s'],
['t','E','E'],
['E','E'],
['E]
]
这是我试过的代码:
const values = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16];
const halfLen = values.length/2 + 1;
var topArr = [];
for(let i = 0; i < values.length; i ++) {
if(i <= halfLen) {
topArr.push(values[i])
}
}
console.log(topArr)
var filTopArr = [];
for(let i = 0; i <= topArr.length; i ++) {
let prevIndex = i - 1;
if(i === 0) {
filTopArr.push(topArr[i])
} else if(i === 1) {
filTopArr.push(topArr.slice(i, i + i + 1))
} else {
filTopArr.push(topArr.slice(i, i + i ))
}
}
console.log(filTopArr)
我的想法是将数组分成两个不同的数组,这两个数组将成为大小递增的顶部部分和大小将减小的 second/bottom 部分。
上面的代码有这样的输出
[1, [2, 3], [3, 4], [4, 5, 6], [5, 6, 7, 8], [6, 7, 8, 9], [7, 8, 9], [8, 9], [9], []]
一些观察:
输出中的字符串数(包括填充“E”字符串)始终是一个完美的平方(1、4、9、16、25 等)
为了知道需要添加多少个“E”字符串,我们因此需要知道哪个是不小于输入大小的最不完美的平方。
输出中最长(中间)的子数组的大小是该完美平方的平方根。
子数组的个数是该数的两倍减1。
这导致以下实现:
function diamond(array) {
// Get least perfect square that is not less than the array length
const sqrt = Math.ceil(Math.sqrt(array.length));
const size = sqrt ** 2;
// Pad the array with "E" strings so to reach that perfect square size
const all = [...array, ..."E".repeat(size - array.length)];
const length = 2 * sqrt;
return Array.from({length}, (_, width) => {
return all.splice(0, Math.min(width, length - width));
}).slice(1); // Skip the first subarray that was produced (empty array)
}
// Demo using the two provided examples:
var array = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p'];
console.log(diamond(array));
var array = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t'];
console.log(diamond(array));
这是一个递归版本。请注意,display
仅用于演示目的。
唯一真正的工作是在 diamond
:
const diamond = (xs, [len = xs.length, up = true, n = 1] = []) => n == 0 ? [] : [
Object .assign (Array (n) .fill ('E'), xs .slice (0, n)),
...diamond (xs .slice (n), up && n * n < len ? [len, true, n + 1] : [len, false, n - 1])
]
const display = (xss) => console .log (`${xss .map (
(xs, i) => `${' '.repeat (Math .abs ((xss .length - 1) / 2 - i) + 1)}${xs .join (' ')
}`) .join ('\n')}`)
const demos = [
['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p'],
['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u'],
[1, 2, 3, 4, 5, 6, 7, 8]
]
demos .forEach (array => display (diamond (array)))
.as-console-wrapper {max-height: 100% !important; top: 0}
我们跟踪当前字符串的长度(n
,默认为1
),原始数组的长度(len
),以及一个布尔标志来判断是否我们的长度正在向上或向下移动 (up
)。我们在初始迭代中增加 n
,将输入中的下一个 n
个字符添加为下一个子数组。当 n
为零时,我们 return 一个空数组。当n ** n
大于或等于len
时,我们将up
切换为false,然后从n
开始减一。唯一需要做的就是用 'E'
填充我们剩余的数组。我们通过 Object .assign
调用来做到这一点。
如果您希望格式化输出更像数组文字形式,您可以使用此版本的 display
:
const display = (xss) => console .log (`[\n${xss .map (
(xs, i) => `${' '.repeat (Math .abs ((xss .length - 1) / 2 - i) + 1)}['${xs .join (`','`)
}']`) .join ('\n')}\n]`)
得到这样的输出:
[
['a']
['b','c']
['d','e','f']
['g','h','i','j']
['k','l','m','n','o']
['p','q','r','s']
['t','u','E']
['E','E']
['E']
]
请注意,此递归有点霸道,具有三个独立的默认递归变量。我很可能会像这样使用 trincot 的解决方案。但是有替代品是很好的。
如何从给定数组生成增量值数组
我们的想法是创建一种菱形,阵列在到达阵列中间后开始缩小尺寸。换句话说,最长的数组将是包含数组中间值的数组或 (array.length/2 + 1)
如果元素短而无法在后半部分完成数组,只需将其替换为 'E' 以指示空 space,就像第二个示例一样。
example 1
var array = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p']
//the longest array in length is containing 'i' which is the value at
array.length/2 + 1
var output = [
['a'],
['b','c'],
['d','e','f'],
['g','h','i','j'],
['k','l','m'],
['n','o'],
['p']
]
example 2
var array = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t']
enter code here
//the longest array in length is containing 'k' which is the value at array.length/2 + 1
var output = [
['a'],
['b','c'],
['d','e','f'],
['g','h','i','j'],
['k','l','m','n','o'],
['p','q','r','s'],
['t','E','E'],
['E','E'],
['E]
]
这是我试过的代码:
const values = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16];
const halfLen = values.length/2 + 1;
var topArr = [];
for(let i = 0; i < values.length; i ++) {
if(i <= halfLen) {
topArr.push(values[i])
}
}
console.log(topArr)
var filTopArr = [];
for(let i = 0; i <= topArr.length; i ++) {
let prevIndex = i - 1;
if(i === 0) {
filTopArr.push(topArr[i])
} else if(i === 1) {
filTopArr.push(topArr.slice(i, i + i + 1))
} else {
filTopArr.push(topArr.slice(i, i + i ))
}
}
console.log(filTopArr)
我的想法是将数组分成两个不同的数组,这两个数组将成为大小递增的顶部部分和大小将减小的 second/bottom 部分。
上面的代码有这样的输出
[1, [2, 3], [3, 4], [4, 5, 6], [5, 6, 7, 8], [6, 7, 8, 9], [7, 8, 9], [8, 9], [9], []]
一些观察:
输出中的字符串数(包括填充“E”字符串)始终是一个完美的平方(1、4、9、16、25 等)
为了知道需要添加多少个“E”字符串,我们因此需要知道哪个是不小于输入大小的最不完美的平方。
输出中最长(中间)的子数组的大小是该完美平方的平方根。
子数组的个数是该数的两倍减1。
这导致以下实现:
function diamond(array) {
// Get least perfect square that is not less than the array length
const sqrt = Math.ceil(Math.sqrt(array.length));
const size = sqrt ** 2;
// Pad the array with "E" strings so to reach that perfect square size
const all = [...array, ..."E".repeat(size - array.length)];
const length = 2 * sqrt;
return Array.from({length}, (_, width) => {
return all.splice(0, Math.min(width, length - width));
}).slice(1); // Skip the first subarray that was produced (empty array)
}
// Demo using the two provided examples:
var array = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p'];
console.log(diamond(array));
var array = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t'];
console.log(diamond(array));
这是一个递归版本。请注意,display
仅用于演示目的。
唯一真正的工作是在 diamond
:
const diamond = (xs, [len = xs.length, up = true, n = 1] = []) => n == 0 ? [] : [
Object .assign (Array (n) .fill ('E'), xs .slice (0, n)),
...diamond (xs .slice (n), up && n * n < len ? [len, true, n + 1] : [len, false, n - 1])
]
const display = (xss) => console .log (`${xss .map (
(xs, i) => `${' '.repeat (Math .abs ((xss .length - 1) / 2 - i) + 1)}${xs .join (' ')
}`) .join ('\n')}`)
const demos = [
['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p'],
['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u'],
[1, 2, 3, 4, 5, 6, 7, 8]
]
demos .forEach (array => display (diamond (array)))
.as-console-wrapper {max-height: 100% !important; top: 0}
我们跟踪当前字符串的长度(n
,默认为1
),原始数组的长度(len
),以及一个布尔标志来判断是否我们的长度正在向上或向下移动 (up
)。我们在初始迭代中增加 n
,将输入中的下一个 n
个字符添加为下一个子数组。当 n
为零时,我们 return 一个空数组。当n ** n
大于或等于len
时,我们将up
切换为false,然后从n
开始减一。唯一需要做的就是用 'E'
填充我们剩余的数组。我们通过 Object .assign
调用来做到这一点。
如果您希望格式化输出更像数组文字形式,您可以使用此版本的 display
:
const display = (xss) => console .log (`[\n${xss .map (
(xs, i) => `${' '.repeat (Math .abs ((xss .length - 1) / 2 - i) + 1)}['${xs .join (`','`)
}']`) .join ('\n')}\n]`)
得到这样的输出:
[
['a']
['b','c']
['d','e','f']
['g','h','i','j']
['k','l','m','n','o']
['p','q','r','s']
['t','u','E']
['E','E']
['E']
]
请注意,此递归有点霸道,具有三个独立的默认递归变量。我很可能会像这样使用 trincot 的解决方案。但是有替代品是很好的。