问题
I want to write a recursive function in javascript that returns an array with its elements reversed. This code generates the following error:
undefined is not a function
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;
}
回答1:
lastOfIndex is not a function, you probably mean to use lastIndexOf. here is a similar way:
function reverseArray (toBeReversed){
var reversed = [];
function reverser (toBeReversed){
if (toBeReversed.length !== 0){
reversed.push( toBeReversed.pop() );
reverser( toBeReversed );
}
}
reverser(toBeReversed);
return reversed;
}
回答2:
A classic recursive implementation would be
function reverse(a) {
if (!a.length) return a;
return reverse(a.slice(1)).concat(a[0]);
}
You don't need any loops, or arrays accumulating values, or functions inside functions, or any other machinery.
If you prefer writing little one-liners to make your code more readable, then
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));
}
This little program has the property that it can be "read" as English, which I think more programs should have. In this case it's
The reverse of an array is (1) empty, if it is empty; (2) otherwise, the result of adding the head to the end of the reverse of the tail.
Unfortunately, even in JS implementations which provide optimized tail recursion (precisely none at this point in time), it will not be applied in this case, since JS has to keep the stack around to call concat on the result of reverse each time around. Can we write something that is optimizable? Yes, by carrying around another value, namely the result of reversing the array so far:
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)));
}
Or if you prefer
function reverse(a) {
return function _reverse(a, result {
if (empty(a)) return result;
return _reverse(tail(a), unshift(result, head(a)));
}(a, []);
}
This is not quite as clean, but gives us the benefit of being able to still think recursively, without the normal stack overhead associated with recursion.
回答3:
const recursiveRev = arr => arr.length === 0 || arr.length === 1 ? arr : arr.slice(arr.length-1).concat(recursiveRev(arr.slice(-arr.length, -1)));
回答4:
This is how I would approach it:
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();
}
Usage:
var letters = ["a", "b", "c", "d", "e", "f", "g", "h"];
var reversed = reverse(letters);
Output:
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"]
回答5:
Try
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>
回答6:
Here is my solution which manipulates the original array.
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);
Link to fiddle: https://jsfiddle.net/octopuscode/opyes4nd/2/
来源:https://stackoverflow.com/questions/28006064/recursively-reverse-the-elements-in-an-array