我想在javascript中编写一个递归函数,返回一个反转元素的数组。此代码生成以下错误:
undefined不是函数
function reverseArray (toBeReversed){
var reversed = [];
function reverser (toBeReversed){
if (toBeReversed.length == 1)
reversed.push(toBeReversed[0]);
else {
reversed.push(toBeReversed.lastOfIndex(0)); //error on this line
reverser(toBeReversed.slice(-1));
}
}
reverser(toBeReversed);
return reversed;
}
答案 0 :(得分:3)
经典的递归实现将是
function reverse(a) {
if (!a.length) return a;
return reverse(a.slice(1)).concat(a[0]);
}
您不需要任何循环,数组累积值,函数内部的函数或任何其他机器。
如果您更喜欢编写小的单行代码以使代码更具可读性,那么
function head(a) { return a[0]; }
function tail(a) { return a.slice(1); }
function push(a, v) { a.push(v); return a; }
function empty(a) { return !a.length; }
function reverse(a) {
if (empty(a)) return a;
return push(reverse(tail(a)), head(a));
}
这个小程序具有可以“读”为英语的属性,我认为应该有更多的程序。在这种情况下,它是
如果数组为空,则数组的反转为(1)为空; (2)否则,将头部添加到尾部反向末端的结果。
不幸的是,即使在JS实现中提供优化的尾递归(此时精确地为none),在这种情况下也不会应用它,因为JS必须保持堆栈调用{{1每次都在concat
的结果上。我们能写一些可以优化的东西吗?是的,通过携带另一个值,即到目前为止反转数组的结果:
reverse
或者如果您愿意
function unshift(a, v) { a.unshift(v); return a; }
function reverse(a) { return _reverse(a, []); }
function _reverse(a, result) {
if (empty(a)) return result;
return _reverse(tail(a), unshift(result, head(a)));
}
这不是很干净,但是给我们的好处是能够递归思考,而不会出现与递归相关的正常堆栈开销。
答案 1 :(得分:2)
lastOfIndex不是函数,你可能意味着使用lastIndexOf。这是一种类似的方式:
function reverseArray (toBeReversed){
var reversed = [];
function reverser (toBeReversed){
if (toBeReversed.length !== 0){
reversed.push( toBeReversed.pop() );
reverser( toBeReversed );
}
}
reverser(toBeReversed);
return reversed;
}
答案 2 :(得分:1)
const recursiveRev = arr => arr.length === 0 || arr.length === 1 ? arr : arr.slice(arr.length-1).concat(recursiveRev(arr.slice(-arr.length, -1)));
答案 3 :(得分:1)
我通过使用递归得出了这个答案
function reverse(arr) {
return (arr.length > 1) ? [arr.pop()].concat(reverse(arr)) : arr.pop();
}
const dataSet = [0, 1, 2, 3, 4];
console.log(reverse(dataSet));
答案 4 :(得分:1)
这一直在复活,但 this answer 似乎很少有任何改进。然而,在现代 JS 中,该算法有一个更好的语法:
const reverse = ([x, ...xs]) =>
x == undefined ? [] : [... reverse (xs), x]
console .log (reverse ([9, 0, 3, 5, 7, 6, 8]))
答案 5 :(得分:0)
尝试
function reverseArray (arr) {
return (function reverser(r, t) {
r.push(t.splice(-1, 1)[0]);
return !!t.length ? reverser(r, t) : r
}([], arr));
};
function reverseArray (toBeReversed) {
return (function reverser(r, t) {
r.push(t.splice(-1, 1)[0]);
return !!t.length ? reverser(r, t) : r
}([], toBeReversed));
};
var rev = document.getElementsByTagName("pre")[0];
document.getElementsByTagName("button")[0]
.addEventListener("click", function(e) {
rev.innerText = "[" + reverseArray(JSON.parse(rev.innerText)) + "]"
})

<pre>[1,2,3,4,5,6,7]</pre><button>click</button>
&#13;
答案 6 :(得分:0)
这就是我接近它的方式:
function reverse(arr) {
var result = [];
var count = arr.length;
function recur() {
if (result.length < arr.length) {
result.push(arr[--count]);
return recur();
} else {
return result;
}
}
return recur();
}
用法:
var letters = ["a", "b", "c", "d", "e", "f", "g", "h"];
var reversed = reverse(letters);
输出:
console.log(reversed);
//=> ["h", "g", "f", "e", "d", "c", "b", "a"]
// Original array is unmodified
console.log(letters);
//=> ["a", "b", "c", "d", "e", "f", "g", "h"]
答案 7 :(得分:0)
这是我操作原始数组的解决方案。
function reverseArr(arr, i, j){
if(i < j){
var temp1 = arr[i];
arr[i] = arr[j];
arr[j] = temp1;
i++;
j--;
return reverseArr(arr,i,j);
} else if(i === j ){
return arr;
}
}
var originalArr = [1,5,7,3,2,9,11];
result = reverseArr(originalArr, 0, originalArr.length-1);
console.log(result);
答案 8 :(得分:0)
let arr = ["1","2","3"]; //declaration of array
function reverseArr(param){
let i=param.length; //set counter i to the array length
if(i==0){ //when to exit recursion
return;
}
console.log(param[i-1]) //what to do until you exit,[i-1] because arrays are 0-based
param.pop(param[i-1]) //pop already printed element from array
reverseArr(param) //pass the new array and invoke function again
}
reverseArr(arr)
答案 9 :(得分:0)
使用递归实现一个非常简单的算法 -
I/P : ["h", "e", "l", "l", "o"] O/P: [ "o" , "l", "l", "e", "h" ]
想法:
如果我能以某种方式取出第一个元素并将其放入最后一个索引中,我的工作就完成了。
说明:
由于我们使用递归,我们可以将数组的第一个元素存储在堆栈中。
现在,我们知道 LIFO 上的堆栈工作。所以,按照上面的原则,如果我的数组的最后一个元素先入栈,如果我们可以先将最后一个元素压入一个空数组,那么我们就可以实现输出。
算法:
代码:
function reverseArray (s) {
if(s.length === 0) { // base case of the recursion
return []
}
let v = s.shift(); // Pop out the first element
reverseArray(s); // repeat the operation for the next element
s.push(v); // Once base case is reached start pushing the last popped element in the array
return s;
}
console.log(reverseArray(["h" , "e", "l", "l" , "o"]))
注意:如果您不清楚递归的工作原理、调用堆栈是什么等。您可能需要阅读 Eric Roberts 的“Thinking Recursively”。
答案 10 :(得分:-1)
这是我对反向函数的解决方案:
function reverser = (array) => {
const reversed = [];
for (let i = array.length-1; i >= 0; i-- ) {
if (Array.isArray(array[i])) {
reversed.push(reverser(array[i]))
} else {
reversed.push(array[i])
}
}
return reversed;
}
const arr1 = [1,2,3,4,5,6,7,8,9]
const arr2 = [[1,2,3],[4,5,6],[7,8,9]]
const arr3 = [[[1,2],[3]],[[4,5],[6]],[[7,8],[9]]]
console.log(reverser(arr1))
console.log(reverser(arr2))
console.log(reverser(arr3))