Array reversing function JS - javascript

A beginner JS question.. I need to write a function that reverses an array that goes as a function's input. (I cannot use a reverse method).
I wonder why this works:
function reverseArrayInPlace(array) {
for (let i = 0; i < Math.floor(array.length / 2); i++) {
let old = array[i];
array[i] = array[array.length - 1 - i];
array[array.length - 1 - i] = old;
}
return array;
}
let arr = [0, 1, 2, 3, 4, 5];
console.log(reverseArrayInPlace(arr))
But this does NOT:
function reverseArrayInPlace(arr) {
let len = arr.length;
for (counter = 0; counter < 2 * len; counter += 2) {
arr.unshift(arr[counter]);
}
arr = arr.slice(0, len);
}
let b = [0, 1, 2, 3, 4, 5];
console.log(reverseArrayInPlace(b));
Looks like arr = arr.slice(0,len); part is not working..I wonder why when:
b = b.slice(0,6);
[5, 4, 3, 2, 1, 0]

If you want to change the input arrray, avoiding return, use splice:
function reverseArrayInPlace(arr) {
let len = arr.length;
for (counter = 0; counter < 2 * len; counter += 2) {
arr.unshift(arr[counter]);
}
arr.splice(len);
}
var b = [0, 1, 2, 3, 4, 5];
reverseArrayInPlace(b);
console.log(b);
EDIT:
If you want to do something like:
console.log(reverseArrayInPlace(b));
your function MUST return something, otherwise the print will always be undefined, even if b has been reverted

arr = arr.slice(0, len);
slice returns a new array which you store inside the local variable arr, that does not change b, which is still pointing to the whole array. To mutate the array you could:
arr.splice(len, len);
and then you have to return arr to log something meaningful.

Because the array is passed to the function by copying the reference, hence you cannot change the external reference from inside the function.

Related

printing elements from an array by alternating first and last

I'm learning for loops in JS and am trying to learn how to console.log the first and last element in an array on one iteration, then console.log the second and second to last elements, etc.
here's what I have tried:
for (let i=0; i<myArray.length; i++){
console.log(myArray[i]);
console.log(myArray[i-1];
}
This is printing elements from my array, but not in the correct order
So what you are trying to achieve is to print the last element, the second last element, etc...
You can use the myArray.length property to do it, just substract the iterator + 1 to the array length and obtain the result you want.
for (let i=0; i<myArray.length; i++){
console.log(myArray[i]);
console.log(myArray[myArray.length - (i + 1)]);
}
The (i + 1) is because the .length property returns the number of item of the array, but not the maximum index of the array. So if the length of the array is 5, the maximum index of the array is 4 (since index starts from 0). You can also write it like: myArray[myArray.length - i - 1]
Here an example:
const myArray = [1, 2, 3, 4, 5];
for (let i=0; i<myArray.length; i++){
console.log(myArray[i]);
console.log(myArray[myArray.length - (i + 1)]);
}
Create a temporary copy of your array, then use shift (to remove the head element) and pop (to remove the tail element) until the copy is empty:
const realArray = [1, 2, 3, 4, 5, 6, 7, 8, 9];
const temporary = realArray.slice();
while (temporary.length) {
const e1 = temporary.shift();
// do something with e1
console.log(e1);
const e2 = temporary.pop();
if (e2) {
// note that e2 _might not exist_ so: always test
console.log(e2);
}
}
You can use two counters that works on opposite direction
i will move forward with increment as i++.
j will move backward with decrement as j--.
If there are even numbers of elements in an array then you should print both numbers arr[i] and arr[j]. But be sure to handle the odd number of elemetns in an array then you have to print either of arr[i] or arr[j]
function print(arr) {
let i = 0;
j = arr.length - 1;
while (i <= j) {
if (i !== j) {
console.log(arr[i], arr[j]);
} else console.log(arr[j]);
i++;
j--;
}
}
print([1, 2, 3, 4, 5, 6, 7, 8]);
print([1, 2, 3, 4, 5, 6, 7, 8, 9]);
Here's one way to do it, reverse the array and use the same index. Since array.reverse() mutates the original array, we slice() it in order to use a copy.
let array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
array.forEach((a, i) => {
let b = array.slice().reverse()[i]
if (i < array.length / 2) console.log(a, b)
})
let output = '';
for (let i = 0; i < (myArr.length) /2; i++){
output += myArr[i] + myArr[myArr.length-1-i];
}
console.log(output)
Just check for i === 0 to indicate the start of the loop and hence, you can print the last element of array
const myArray = ['first', 1, 2, 3, 'last'];
for (let i = 0; i < myArray.length - 1; i++) {
console.log(myArray[i]);
if (i === 0) {
console.log(myArray[myArray.length - 1]);
}
}

How to calculate the difference between of the elements in an array starting from the last up to the first in JavaScript?

This is an array given:
arrayNum = [1, 2, 4, 5, 8, 9];
arrayS = [];
for(var i=1, len = array1.length; i<len; i++){
arrayS.push(arrayNum[i]-arrayNum[i-1]);
}
console.log(arrayS);
This code calculates the difference between each two consecutive elements!
However I need to calculate the difference between elements starting from the last up to the first element what would be in this particular case 9-8-5-4-2-1 = -11?!
s1=0;
for(var j=array1[array1.length-1]; j>0; j--){
s1 = s1 - array1[j];
}
console.log(s1);
However this is not working!
In your original solution, you should iterate the index, rather than the element
const arrayNum = [1, 2, 4, 5, 8, 9];
s1 = arrayNum[arrayNum.length - 1];
for (var j = arrayNum.length - 2; j >= 0; j--) {
s1 = s1 - arrayNum[j];
}
console.log(s1);
Or you could use reduce
const arrayNum = [1, 2, 4, 5, 8, 9];
const res = arrayNum.reduce(
(acc, el, index) => acc + (index !== arrayNum.length - 1 ? -1 : 1) * el,
0
);
console.log(res);
You can use Array.reduceRight() to calculate the difference from the end of the array.
Note: that reduce/reduceRight would throw an error when reducing an empty array without an initial value. I use a ternary to check the length, and if it's empty return NaN.
const fn = arr =>
arr.length ?
arrayNum.reduceRight((s, n) => s - n) // if array is not empty
:
NaN // if array is empty
const arrayNum = [1, 2, 4, 5, 8, 9];
const result = arrayNum.reduceRight((s, n) => s - n)
console.log(result);
For the for loop to work, you need to initialize s1 without setting a value, and j with the last index. When calculating s1 check if it's undefined, and initialize it with the current number. If it's not, subtract the current number:
const array1 = [1, 2, 4, 5, 8, 9];
let s1;
for (let j = array1.length - 1; j >= 0; j--) {
s1 = s1 === undefined ? array1[j] : s1 - array1[j];
}
console.log(s1);
Expression 9-8-5-4-2-1 is equal to -(-9+8+5+4+2+1).
-9+8+5+4+2+1 is equal to (-(9*2) + (9+8+5+4+2+1)).
const arrayNum = [1, 2, 4, 5, 8, 9];
const res = -arrayNum.reduce((acc, num) => acc + num
, -arrayNum[arrayNum.length - 1] * 2)
console.log(res)
Issue is with var j=array1[array1.length-1];, not correct index to start with in for-loop.
Try the while loop, should simplify for this case.
array1 = [1, 2, 4, 5, 8, 9];
s1 = array1[array1.length-1];
j = array1.length-1;
while (--j >= 0) s1 -= array1[j];
console.log(s1);

JS: Reverse an Array but Reverse the Original Array Only --> Error: running with no output

I have following problem:
// Reverse Array
Write a function that accepts an array and reverses that array in place. The behavior should mimic the behavior of the native .reverse() array method. However, your reverse function should accept the array to operate on as an argument, rather than being invoked as a method on that array.
Do not use the native .reverse() method in your own implementation.
I tried the following code:
let myArray = [1, 2, 3, 4];
function reverse(myArray) {
let newArray = [];
// pop all of elements from roginal array, and store in new array
for (i=myArray.length-1; i>=0; i--){
newArray.push(myArray[i])
console.log(newArray)
}
while (newArray.length){
myArray.unshift(newArray)
}
return myArray;
}
reverse(myArray);
console.log(myArray) // expected output is [4, 3, 2, 1]
My code just keeps running and no console.log output is produced. Notice I want the reverse done to the input array argument.
What am I doing wrong? Also, what does while (newArray.length) mean / what is it doing conceptually?
Not sure why you need the unshift you can just iterate and return the array where you are pushing the value
let myArray = [1, 2, 3, 4];
function reverse(myArray) {
let newArray = [];
for (i = myArray.length - 1; i >= 0; i--) {
newArray.push(myArray[i])
}
return newArray;
}
console.log(reverse(myArray))
You can iterate the array 'till the middle, and switch between the current (i) and the opposite (length - i - 1):
const myArray = [1, 2, 3, 4];
function reverse(myArray) {
const length = myArray.length;
const middle = Math.floor(length / 2);
for(let i = 0; i < middle; i++) {
let tmp = myArray[i];
myArray[i] = myArray[length - i - 1];
myArray[length - i - 1] = tmp;
}
}
reverse(myArray);
console.log(myArray) // expected output is [4, 3, 2, 1]
You can swap first and last element in an array and iteratively swap the next and prev respectively.
You don't have to visit the complete set in the loop, get the middle element and rotate the index around that
function reverseInArray(arr){
let len = arr.length;
let temp;
for(let i=0; i < len/2; i++){
temp = arr[i];
arr[i] = arr[len - i - 1];
arr[len - i - 1] = temp;
}
return arr;
}
console.log(reverseInArray([1,2,3,4,5]));
You could swap the first and the last element and start from the most inner item.
function reverse(array) {
var i = array.length >> 1, // take half of the length as integer
l = array.length - 1; // last index value to calculate the other side
while (i--) [array[i], array[l - i]] = [array[l - i], array[i]];
}
var a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
reverse(a);
console.log(...a);
Just swap pairs starting at either end of the array, until there's none left:
function reverse(a) {
for (let i = 0, j = a.length - 1; i < j; ++i, --j) {
let tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
return a; // not required, but allows use in an expression
}
In ES2016 you can use destructuring assignments to perform the swap in one operation without the use of a temporary variable:
function reverse(a) {
for (let i = 0, j = a.length - 1; i < j; ++i, --j) {
[ a[j], a[i] ] = [ a[i], a[j] ];
}
return a;
}
Here:
while (newArray.length){
myArray.unshift(newArray)
}
You're adding to myArray, but not taking from newArray, hence infinite loop. Methinks it should be myArray.unshift(newArray.pop()).

Move every other value from array into a new array

I have two one-dimensional arrays, a and b. a has values and b is empty. The length of a is an even number. I'd like to remove every other value from a and move them to b, in the same order as they were placed in a.
var a = [1, 2, 3, 4, 5, 6], b = [];
becomes
var a = [1, 3, 5], b = [2, 4, 6];
I figured that filter would do the trick but I'm not that happy with the performance of it since the average length of a is 300-400.
b = a.filter((i, idx) => {
return idx % 2 == 0;
});
a = a.filter((i, idx) => {
return idx % 2 == 1;
});
I've also been looking at lodash to see if that library had anything that might help me and the only function that's near what I'm looking for is _.chunk(array, \[size=1\]).
I appreciate any and all help to help me figure out a better, faster way to do this.
Since you mentioned lodash you could do this with _.partition:
let a = [1, 2, 3, 4, 5, 6];
let b = [];
let i = -1;
[a, b] = _.partition(a, (item) => i++ % 2);
console.log(a);
console.log(b);
<script src="https://cdn.jsdelivr.net/lodash/4.17.4/lodash.min.js"></script>
Partition's predicate is the identity function, which doesn't include the index of the item, so this comes with a compromise of an external index i.
Of course, you could always wrap this functionality into it's own function:
const splitEvenOdd = (array, i = -1) => _.partition(array, (item) => i++ % 2);
let a = [1, 2, 3, 4, 5, 6];
let b = [];
[a, b] = splitEvenOdd(a);
console.log(a);
console.log(b);
<script src="https://cdn.jsdelivr.net/lodash/4.17.4/lodash.min.js"></script>
Vanilla JS ES5, simple and clean.
var a = [1, 2, 3, 4, 5, 6], b = [];
for(var i = a.length-1; i >= 0; i--) {
if(i % 2 === 1) {
b.unshift(a.splice(i, 1)[0])
}
}
Basically, it is iterating through a backwards, and if the condition is true splicing the item und adding it as first item of b.
To loop through the source once, the values can be added to a specific array depending on the index. For example:
const source = [1, 2, 3, 4, 5, 6];
let arrs = [[],[]];
for(let i = 0; i< source.length; i++)
arrs[i%2].push(source[i]);
let [a,b] = arrs;
console.log(a);
console.log(b);
Alternatively, if it's important to alter the original arrays, a can be filled in a direct iteration, since the index being processed is always ahead of the one being filled:
let a = [1, 2, 3, 4, 5, 6], b= [];
for(let i = 0; i< a.length; i++)
(i % 2 ? b : a)[Math.floor(i/2)] = a[i];
a.splice(a.length/2);
console.log(a);
console.log(b);
The best performance you can get for this is 0(n) or linear time since you have to iterate through the entire array. What may help is reducing the number of loops
var a=[];
var b=[];
function splitArray(arr)
{
for (var i=0;i<arr.length;++i)
{
if (arr[i]%2 == 0)
b.push(arr[i]);
else
a.push(arr[i]);
}
}
What this does is reduces the number of times you have to iterate through the original array from 2 to 1

Make average of values inside array to smooth graph line

I have an array which represents the points of a graph with different values like the following one:
var array = [5, 3, 4, 1, 2];
I would like to loop through it and create a new array where the new values are:
An average between the value preceding it and the one coming after it.
Placed among the existing ones.
This means that array[0] will remain at the same position, while the other values will be pushed of one position. The new array should look like this:
var newArray = [5, 4, 3, 3.5, 4, 2.5, 1, 1.5, 2];
Do you have an idea on how to achieve this? Thanks in advance to your replies!
var array = [5, 3, 4, 1, 2];
var newArr = [array[0]]; // start the array with the first from the original
array.reduce((a, b) => {
newArr.push((a + b) / 2, b);
return b;
});
console.log(newArr);
var array = [5, 3, 4, 1, 2];
var newArray = [];
newArray.push(array[0]);
for(var i=0; i < array.length-1; i++)
{
var first = array[i];
var second = array[i+1];
var avg = (first+second)/2;
newArray.push(avg);
newArray.push(second);
}
https://jsfiddle.net/5utkvge8/
You are going to want to loop through your original array, pushing each number to the new one, and if you are not on the final element, get the average of array[i] and array[i+1]
var array = [5, 3, 4, 1, 2];
var newArray = [];
for (var i = 0; i < array.length; i++)
{
newArray.push(array[i])
if (!isNaN(array[i+1]))
{
newArray.push((array[i] + array[i+1]) / 2)
}
}
or in a functional, no-side effects, way:
var array = [5, 3, 4, 1, 2];
var newArray = array.reduce((result, value, index, array) => result.concat(index > 0 && index < array.length ? [(array[index-1] + value)/2, value] : value), [])
In case you can modify the original array:
var array = [5, 3, 4, 1, 2],
len = array.length * 2 - 2;
for (var i = 1; i < len; i = i + 2) {
array.splice(i, null, (array[i-1] + array[i]) / 2);
}
console.log(array);
let createdArr = []
[5, 3, 4, 1, 2].forEach( (item,index,arr) => {
createdArr.push(item)
if( index !== 0 && index + 1 !== arr.length ){
createdArr.push( (item + arr[ index + 1]) / 2 )
}
} )

Categories