我做了一个将数组变成列表的函数,如下所示:
function arrayToList(array) {
var result = null;
for (var i = array.length; i >= 0; i--) {
result = {
value: array[i],
rest: result
}
}
return result
}
console.log(arrayToList([10, 20]))
然后我尝试制作一个递归函数,该函数需要一个列表和一个数字,并在列表中的给定位置返回一个元素
这是第一次尝试:
function arrayToList(array) {
var result = null;
for (var i = array.length; i >= 0; i--) {
result = {
value: array[i],
rest: result
}
}
return result
}
function nthRecur(list, index) {
var counter = 0
if (counter === index) {
return list.value
} else {
counter++
list = list.rest
return nthRecur(list, index)
}
}
console.log(nthRecur(arrayToList([10, 20, 30]), 1))
第二次尝试:
function arrayToList(array) {
var result = null;
for (var i = array.length; i >= 0; i--) {
result = {
value: array[i],
rest: result
}
}
return result
}
function nthRecur(list, index) {
var counter = 0
if (counter === index) {
return list.value
} else {
list = list.rest
return nthRecur(list, index - 1)
}
}
console.log(nthRecur(arrayToList([10, 20, 30]), 1))
它奏效了。我不知道为什么有人可以解释吗?
答案 0 :(得分:2)
您可以直接使用索引来缩短它。
function arrayToList(array) {
var result = null,
i = array.length;
while (i--) {
result = { value: array[i], rest: result };
}
return result;
}
function nthRecur(list, index) {
return index
? nthRecur(list.rest, index - 1)
: list.value;
}
var list = arrayToList([10, 20, 30]);
console.log(list);
console.log(nthRecur(list, 1));
答案 1 :(得分:1)
问题在于此counter
是局部变量,并且在每个递归调用中将其设置为0
。您需要创建一个包装函数,并在其中声明counter
。
var counter = 0;
function arrayToList(array)
{
var result = null;
for (var i = array.length; i >= 0; i--)
{
result = {
value: array[i],
rest: result
}
}
return result
}
function nthRecur(list, index)
{
let counter = 0;
function helper(list){
if(counter === index)
{
return list.value
}
else
{
counter++
list = list.rest
return helper(list)
}
}
return helper(list);
}
console.log(nthRecur(arrayToList([10, 20, 30]), 1));
答案 2 :(得分:0)
要改进Nina Scholz's answer,您可以为每个递归添加其他检查,以防止超出范围的索引抛出错误:
text.js
如果您还想支持负索引,类似于slice()
和splice()
,则需要另一个函数来获取列表的function arrayToList (array) {
return array.reduceRight(
(rest, value) => ({ value, rest }),
null
);
}
function item (list, index) {
return list
? index
? item(list.rest, index - 1)
: list.value
: undefined;
}
const list = arrayToList([10, 20, 30]);
console.log(item(list, 0));
console.log(item(list, 1));
console.log(item(list, 2));
console.log(item(list, 3));
,然后调整{{ 1}}的功能:
length
P.S。上面的item
使用reduceRight()
来简化实现。 function arrayToList (array) {
return array.reduceRight(
(rest, value) => ({ value, rest }),
null
);
}
function length (list, index = 0) {
return list
? length(list.rest, index + 1)
: index;
}
function item (list, index) {
return list
? index
? index > 0 || (index += length(list)) > 0
? item(list.rest, index - 1)
: index < 0
? undefined
: list.value
: list.value
: undefined;
}
const list = arrayToList([10, 20, 30]);
console.log(item(list, 0));
console.log(item(list, 1));
console.log(item(list, 2));
console.log(item(list, 3));
console.log(item(list, -1));
console.log(item(list, -2));
console.log(item(list, -3));
console.log(item(list, -4));
可以使用spread syntax和递归来简化其实现:
arrayToList()