I was reading the eloquent book, did a little assignment and ran into something that i can't really figure out. why return gives one answer and console.log gives a different one?
function reverseArrayInPlace(r){
var z = [];
for(var c = (r.length)-1;c>=0;c--){
z.push(r[c]);
}
console.log(z);
return z;
}
var arrayValue = [1, 2, 3, 4, 5];
reverseArrayInPlace(arrayValue);
console.log(arrayValue);
// → [5, 4, 3, 2, 1]
Result:
[5, 4, 3, 2, 1] <- console.log(z)
[1, 2, 3, 4, 5] <- return z
You aren't reversing the array in place. You are creating a new array that is returned by reverseArrayInPlace
EDIT: SOLUTION
Instead of creating a new array and returning it, simply replace the contents of the original array with the one you reversed by using this line at the end of your function:
r.splice.apply(r,[0,r.length].concat(z))
This line removes all elements from array r and replaces them with all elements from array z and then you can simply return r
function reverseArrayInPlace(r){
var z = [];
for(var c = (r.length)-1;c>=0;c--){
z.push(r[c]);
}
console.log(z);
r.splice.apply(r,[0,r.length].concat(z));
return r;
}
var arrayValue = [1, 2, 3, 4, 5];
reverseArrayInPlace(arrayValue);
console.log(arrayValue);
To reverse the array "in place," work on the original array rather than creating a new one:
function reverseArrayInPlace(r) {
var t, i, j;
for(i = 0, j = r.length - 1 ; i < j ; i++, j--) {
t= r[i];
r[i]= r[j];
r[j]= t;
}
}
var arrayValue = [1, 2, 3, 4, 5];
reverseArrayInPlace(arrayValue);
console.log(arrayValue);
z is not the same array as arrayValue. Inside your function you create a new array, called z, where you will push arrayValue's elemenets in reversed order. Instead of that, might I suggest the following:
function reverseArrayInPlace(r){
var aux;
for(var c = 0; c < r.length / 2; c++){
aux = r[c];
r[c] = r[r.length - 1 - c];
r[r.length - 1 - c] = aux;
}
}
arrays are passed by reference by default, so if you call reverseArrayInPlace(arrayValue), then after it is executed, arrayValue will be in reversed order. Note, that you are traversing only half of the array, since if you traverse the whole array, then you will switch the elements back.
Related
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]);
}
}
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()).
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.
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
I've been on this problem for about 3 hours and I can't figure this out. I've gone through Codecademy and Code School Javascript courses, and according to the blog that hosted this code block, I should know the answer:
var merge = function(array1, array2, callback){
//your code here.
}
var x = merge([1, 2, 3, 4], [5, 6, 7, 8], function(a, b){
return a + b;
});
//x should now equal [6, 8, 10, 12].
UPDATED WITH CORRECT CODE (Thank you so much T.J.!):
var merge = function(array1, array2, callback) {
var i, newArray = [];
for (i=0; i < array1.length; i++) {
newArray[i] = callback(array1[i], array2[i]);
}
return newArray;
};
var x = merge([1, 2, 3, 4], [5, 6, 7, 8], function(a, b){
return a + b;
});
console.log(x);
In merge, you:
Create a new, blank array for the return value.
Consider what you want to do if array1 and array2 aren't the same length, although they are in the example usage.
Use an index variable to loop from 0 through < array1.length (most likely a for loop).
Fill in the entry for each index in your return value array by calling callback, passing the entry for that index from array1 and from array2 in as arguments and storing its return value in your array.
Return the new array.