4

I'm trying to solve the following exercise:

Reverse an array without using the reverse method, without using a second array, and without duplicating any of the values.

I've thought about making the array an object and then updating the array from the end to the beginning but I figured you can just update it as well.

Tried something simple like:

function reverseArray(array) {
  for (var i = 0; i < array.length; i++) {
    // var elem = array.shift();
    var elem = array.shift()
    array.push(elem)
  }
  return array
}

array = ['a', 'b','c','d','e'];

reverseArray(array);

But that doesn't really change it. Any advice or explanation on how to do this?

sergdenisov
  • 8,327
  • 9
  • 48
  • 63
  • I would look into this post It is in java but the concepts should still work. https://stackoverflow.com/questions/5985365/how-to-reverse-a-list-with-o1-space-and-on-time – Michael Warner Aug 31 '17 at 19:29
  • 1
    *"without duplicating"*: what does that requirement mean? That you are not allowed to take a copy of an array value? – trincot Aug 31 '17 at 19:30
  • 2
    I would still like the OP to explain what "without duplicating" means... – trincot Aug 31 '17 at 19:41
  • Yes, I can't make a temporary array and push values into it. –  Aug 31 '17 at 19:41
  • But that is a different requirement. You have (1) *without using a second array*, and (2) *without duplicating any of the values.*. What is that second requirement about? I mean, you duplicate a value as soon as you do `temp = a[i]`, right? – trincot Aug 31 '17 at 19:42
  • 2
    No answer to that question about the exact meaing of the last requirement? – trincot Aug 31 '17 at 19:58
  • 1
    Are the elements any specific type? [How do you swap two integer variables without using any if conditions, casting, or additional variables?](https://stackoverflow.com/questions/3262409/how-do-you-swap-two-integer-variables-without-using-any-if-conditions-casting) – Bernhard Barker Aug 31 '17 at 20:14
  • Please [research](https://stackoverflow.com/search?q=[js]+reverse+array+in-place) before asking – Bergi Aug 31 '17 at 21:02

10 Answers10

9

With ES6 syntax you don't need to copy a value into a temporary variable (is that what the last requirement is about?).

function reverse(arr) {
    for(let i = 0, j = arr.length-1; i < j; i++, j--)
        [arr[i], arr[j]] = [arr[j], arr[i]];
}

const arr = ['a','b','c','d','e'];
reverse(arr);
console.log(arr);

One may argue that arrays are created here (if engines don't optimise this away), just like splice also creates an array (as its return value).

trincot
  • 317,000
  • 35
  • 244
  • 286
4

array = ['a', 'b', 'c', 'd', 'e'];
console.log(array);

for (var i = 0; i < Math.floor(array.length / 2); i++) {
  var item = array[i];
  array[i] = array[array.length - i - 1];
  array[array.length - i - 1] = item;
}
console.log(array);
sergdenisov
  • 8,327
  • 9
  • 48
  • 63
3

Here is a minimal approach. Given var arr = [1,2,3,4], this loop will mutate arr to [4,3,2,1]:

for (var i = 0; i < arr.length - 1; i++) {
    arr.splice(i, 0, arr.pop());
}
jmrah
  • 5,715
  • 3
  • 30
  • 37
1

The following will work reverse an array without using the reverse method. It works by swapping the first and last elements, then the second and second-to-last elements, then the third and third-to-last elements, etc until the i is no longer less than (<) than j.

function reverse(arr) {
  for(var i = 0, j = arr.length-1; i < j; i++, j--) {
    var tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
  }
  return arr;
};

var reversed = reverse(['a','b','c','d','e']);
console.log(reversed);
Paul Fitzgerald
  • 11,770
  • 4
  • 42
  • 54
  • 1
    This works by swapping the first and last elements, then the second and second-to-last elements, then the third and third-to-last elements, etc. – Duncan Thacker Aug 31 '17 at 19:35
1

https://jsfiddle.net/pa2fqa8n/1/

a = ['a', 'b', 'c', 'd', 'e'];
for(var i = 0; i < a.length-1; i++){
  for(var j = 0; j < a.length-i-1; j++){
    var k = a[j];
    a[j] = a[j+1];
    a[j+1] = k;
  }
}

First iteration of inner loop moves the first element to the end, and the rest of the elements forward once. Each following iteration does the same thing, but 1 less than the previous iteration.

lancew
  • 780
  • 4
  • 22
1

Here's how, without copies, temporary arrays or variables to hold values, or using Array.reverse().Modifying the array in place

function reverseArray(array) {
  var len = array.length;
  for (var i=len,j=-1; j++,i--;)  array.unshift( array[len-1-i+(j)] );
  array.length = len;
}

var array = ['a', 'b','c','d','e'];

reverseArray(array);
console.log(array);

It inserts the values backwards into the beginning of the array, pushing the old values to the end, and then slicing them of by resetting the arrays length after the iteration has completed.

adeneo
  • 312,895
  • 29
  • 395
  • 388
  • This copies all the elements in the array though. Also, wouldn't it be a lot more efficient to append rather than prepend? – Bernhard Barker Aug 31 '17 at 20:24
  • @Dukeling - any solution would "copy" the elements, that what's moving them does. If I appended the values, I'd have to slice the array, which would create a new array, cutting the array with `length` only works if the new values are at the beginning. – adeneo Aug 31 '17 at 20:35
  • This takes O(n) extra space, by duplicating each element in the array (which, in my mind, clearly violates "without duplicating any of the values"), where-as [this](https://stackoverflow.com/a/45989220/1711796), for example, appears to (based on my limited JS knowledge) just take O(1) extra space. – Bernhard Barker Aug 31 '17 at 21:22
  • @Dukeling - that's destructuring, it's really just syntactic sugar. It will be slower than just using a temporary variable, but it does avoid actually declaring that variable in the code. This does that as well, but using `unshift` would be even slower. – adeneo Aug 31 '17 at 23:12
1

I had to use a swap variable, does that violate "without duplicating any of the values"?

var test1 = [2, '5', 6, 'a', 'Z'];
var test2 = [2, '5', false, 'a', 'Z', {a: 'whatevs'}];

console.log('test1 before', JSON.stringify(test1));
console.log('test2 before', JSON.stringify(test2));

reversarooni(test1);
reversarooni(test2);

console.log('test1 after', JSON.stringify(test1));
console.log('test2 after', JSON.stringify(test2));

function reversarooni(inputArray) {
  var index = 0;
  var len = inputArray.length;
  
  for(; index < len / 2; index++) {
    var swap = inputArray[index];
    inputArray[index] = inputArray[(len - 1) - index];
    inputArray[(len - 1) - index] = swap;
  }
}
Anony372
  • 494
  • 2
  • 15
0

You could use a spread syntax ..., rest parameters ... and return the swapped items with a recursive and functional approach.

const
    _ = (...a) => a,
    rev = (a, ...rest) => rest.length ? _(...rev(...rest), a) : _(a),
    reverseArray = array => rev(...array);

console.log(reverseArray(['a', 'b', 'c', 'd', 'e']));
console.log(reverseArray(['a']));
console.log(reverseArray(['a', 'b']));
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
0

function reverseArray(a) {

    const halfLength = a.length / 2;
for (let i = 0; i< halfLength; i++){
const start = a[i]
a[i] = a[a.length-i-1]
a[a.length-i-1] = start
}
   

return a;
}
-1

function printReverse(array) {
  for (i = array.length-1; i > -1; i--) {
    console.log(array[i]); //4,3,2,1
  }
}

printReverse([1, 2, 3, 4]);

This worked for me.

Roy Scheffers
  • 3,832
  • 11
  • 31
  • 36
coderMom
  • 19
  • 4