Inserted array shows in reverse JS - javascript

I am just starting to learn js and as many (I'm sure) I am facing problems lol. I am trying to copy an array into another array at a designated index location.
I seem to be able to do everything correct but when I log the result, the inserted array shows in reverse and I have no idea why¿?¿?.
Have also tried a .forEach as looping method, but I'm still a bit green to use it right.
This is the code:
function frankenSplice(arr1, arr2, n) {
let newArr = arr2.slice([]);
for (let i = 0; i < arr1.length; i++) {
newArr.splice(n, 0, arr1[i]);
console.log(newArr)
}
}
frankenSplice([1, 2, 3], [4, 5, 6], 1);
It logs // [ 4, 3, 2, 1, 5, 6 ] instead of the desired out: [ 4, 1, 2, 3, 5, 6 ]

You are inserting the elements at the same index, so after inserting 1 you insert 2 at the same position, shifting back the 1 and all following elements.
Either iterate backwards over arr1 or increment n after each iteration like I have done here.
function frankenSplice(arr1, arr2, n) {
let newArr = arr2.slice([]);
for (let i = 0; i < arr1.length; i++) {
newArr.splice(n, 0, arr1[i]);
console.log(newArr)
n++; // add this
}
}
frankenSplice([1, 2, 3], [4, 5, 6], 1);

Related

How can I remove items from an array having met specific conditions in-place?

I am working on what i thought is a simple algorithm:
Task: Look at the given array, take only the even numbers and multiply them by 2. The catch is to modify the array in its place and NOT create a new array.
I can loop/map through an array and figure out what numbers are even, so
I got this far:
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
arr.forEach((x, y) => {
if (x % 2 !== 0) {
// I would like to splice those numbers,
// but can't figure out how to do it?
}
})
Again, the catch is that modifying the original array is not allowed, returning 4, 8, 12, 16, and 20.
This is not a good approach in my opinion, but if you insist on modifying the existing array without creating a new one, this should do the job:
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let i = 0;
while (i < arr.length) {
if (arr[i] % 2 === 0) {
arr[i] *= 2;
} else {
arr.splice(i, 1);
i--;
}
i++;
}
console.log(arr.join(", "));
The i-- comes into play, because when you splice the current index (where the next element will be after the splice) and you execute i++, it's going to skip the current index. The same effect can possibly be achieved by adding i++ in the if block and remove the i-- in the else block.
First of all.
Why would you do that? If you don't want the old array just take the new one.
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
const evenNumbers = arr.filter(item => item % 2 === 0)
Unless it's something required, explore all Js Array methods, always are multiple ways to get to an answer. Try to make your life easy.
Like the example before you will have the old and the new. Take wherever you need.
You could take a different approach and loop from start by using a new index for all items to keep and later adjust the length of the array.
const
array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let l = 0; i = 0;
while (i < array.length) {
console.log(...array);
if (array[i] % 2 === 0) array[l++] = array[i] * 2;
i++;
}
array.length = l;
console.log(...array);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can use Array.prototype.filter() and Array.prototype.map()
Code:
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
const result = arr
.filter(n => n % 2 === 0)
.map(n => n * 2)
console.log(result)
Could this be what you had in mind?
const arr=[1,2,3,4,5,6,7,8,9,10];
for (let i=arr.length-1;i>=0;i--)
if(arr[i]%2>0) arr.splice(i,1)
arr.forEach((v,i,a)=> a[i]=v*2)
console.log(arr);
As you want to remove elements from an array you are looping over, it is important that you start from the end and work your way down to 0 since going forward you would skip an element as soon as you remove one.

Remove duplicates in array by checking if its the same as the next one

I am learning JavaScript right now and I want to practice for loops and if statements. So I found a little exercise: Remove all duplicates in the array. I know there a probably better solutions but I want to know why my code isn't working. Can someone help me? Thx :)
var arr = [1, 1, 2, 3, 3, 3, 4, 5, 5];
var b = 0;
function arrRemover() {
for (i = 0; i < arr.length; i++) {
b++
if (arr[b] == arr[b + 1]) {
arr.splice[b + 1];
}
}
return arr;
}
console.log(arrRemover());
splice is a method so you have to call that method with specific arguments.
You don't need b here
Better not to loop over that array from start instead loop from backward so that you won't skip over elements when you remove any element from an array beause if an elment gets deleted and you then counter increment and skip some elements
var arr = [1, 1, 2, 3, 3, 3, 4, 5, 5];
function arrRemover() {
for (let i = arr.length - 1; i > 0; i--) {
if (arr[i] === arr[i - 1]) {
arr.splice(i, 1);
}
}
return arr;
}
console.log(arrRemover());
You can also use Set here as:
var arr = [1, 1, 2, 3, 3, 3, 4, 5, 5];
function arrRemover() {
return [...new Set(arr)];
}
console.log(arrRemover());

Using Recursion in JavaScript to shift Array elements to different positions

I know this question has been asked a lot, but I've yet to find a solution that is in JavaScript (a lot of Java and C++) using recursion, and not new/old index splicing. This is merely an exercise and I'm not great at recursion, so any assistance and a thorough explanation would be greatly appreciated.
//given an array, shift all elements within the array forward 2 positions.
// [1, 2, 3, 4, 5] --> [4, 5, 1, 2, 3]
My first line of thought was to use a placeholder of some sort but I'm not sure what to do with it exactly. This is what I have so far
let array = [1, 2, 3, 4, 5];
function shiftTwo (arr) {
for (i=0; i<arr.length; i++) {
let curr = arr[0];
}
}
Thanks in advance!
One possibility is to recur on the number of spaces to move. If it's 0, return the array intact (or possibly clone it with arr.slice(0)); otherwise, shift the last entry to the front and recur with one less. The code might look like this:
const shiftRight = (n, arr) =>
n <= 0
? arr
: shiftRight (n - 1, [...arr.slice(-1), ...arr.slice(0, -1)])
console .log (shiftRight (2, [1, 2, 3, 4, 5]))
Here is a solution using recursion:
function shiftArr(arr, n) {
if (n<=0) {
return arr;
}
else{
arr.unshift(arr.pop());
return shiftArr(arr,n-1)
}
}
//test:
console.log(shiftArr([1, 2, 3, 4, 5],2)); // [4, 5, 1, 2, 3]

Delete numbers below a certain number in an array

Today i'm facing a really weird problem.
I'm actually trying to delete numbers below a certain number in an array.
I have this array [1, 7, 2, 3, 90, 4, 70, 20] and I only want the numbers greater than 20 !
So I should have that in output : [90, 70]
But Instead I have this array : [7, 3, 90, 70, 20] ???
Here is my code :
function superior() {
var arr = [1, 7, 2, 3, 90, 4, 70, 20]
for (var i = 0; i < arr.length; i++) {
if (arr[i] < 20) {
arr.splice(arr.indexOf(arr[i]), 1);
} else {
break;
}
}
return arr;
}
console.log(superior());
Mutating an array while you're looping through it is always going to be tricky. If you shrink the size of the array, but don't change i, then you're can end up interacting with the wrong element of the array the next time through the loop. Also, using break will stop the loop from running entirely, and so skip the rest of the array. You may have meant to use continue, but since you're on the last line of the loop anyway, continue isn't needed.
Rather than trying to change the array and loop through it at the same time, i'd recommend creating a new array. Then you can loop through the old one unhindered:
const arr = [1, 7, 2, 3, 90, 4, 70, 20]
const newArr = []
for (const i = 0; i < arr.length; i++) {
if (arr[i] >= 20) {
newArr.push(arr[i]);
}
}
console.log(newArr)
Filtering an array like this is a very common thing to do, so there are built in tools to do it for you. Every array has a .filter method. You pass into it a function describing what elements you want to keep, and it will produce the new array for you:
const arr = [1, 7, 2, 3, 90, 4, 70, 20]
const newArr = arr.filter(element => element >= 20);
console.log(newArr)
You can filter them out according to a condition.
And replace your existing array with the filtered one. Or if you don't want to replace it, use another variable and assign the filtered value to that variable.
var newArray = array.filter(item => item > 20)
Check .filter()
var array = [1, 7, 2, 3, 90, 4, 70, 20];
array = array.filter(item => item > 20)
console.log(array)
You can use Array.filter()
var arr = [1, 7, 2, 3, 90, 4, 70, 20]
var filteredArr = arr.filter(item => item > 20);
console.log(filteredArr);
You could iterate from the end and omit indexOf, because you have already the index i.
This appoach loops from the end and after splicing, the remaining lower indices remains.
function superior() {
var array = [1, 7, 2, 3, 90, 4, 70, 20],
i = array.length;
while (i--) if (array[i] < 20) array.splice(i, 1);
return array;
}
console.log(superior());
Use temporary array to push new values.
function superior() {
var arr = [1, 7, 2, 3, 90, 4, 70, 20];
temp_arr = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i] > 20) {
temp_arr.push(arr[i]);
}
}
return temp_arr;
}
console.log(superior());

splice odd/evens numbers in multidimensional array but result one or two odd/numbers show off

i am trying to splice the odd/evens numbers, look this, i tried to find odd numbers , but on the results array, evens numbers still there ,
function find(index){
for(var i = 0 ; i < index.length;i++) {
for(var j = 0 ; j < index[i].length ; j++) {
if(index[i][j] % 2 === 1) { // trying to find odd numbers
index[i].splice(j, 1)
}
}
}
return index
}
var data = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
var another = [
[2, 2, 7],
[1, 3, 5, 6],
[1, 3, 5, 7, 9, 11]
]
console.log(find(data))
console.log(find(another))
is there any wrong with my codes ?? or i missed something? :)
The problem is that you are mutating the array as you loop over it.
ie. on the second row of your second array, ([1,3,5,6]), lets think about what happens:
i =1, j = 0
the number (1) is odd, so you splice it, the array now looks like [3,5,9]
i = 1, j = 1, the number is 5, is odd, so you remove it. You skipped over 3.
i = 1, j=2, length of the row is 2, so the loop ends.
I've added a console log to your code that demonstrates this.
function find(index){
for(var i = 0 ; i < index.length;i++) {
for(var j = 0 ; j < index[i].length ; j++) {
if (i ===1) console.log(`i = ${i}, j=${j}, index[i] = ${index[i]}, index[i].length=${index[i].length}`);
if(index[i][j] % 2 === 1) { // trying to find odd numbers
index[i].splice(j, 1)
}
}
}
return index
}
var another = [
[2, 2, 7],
[1, 3, 5, 6],
[1, 3, 5, 7, 9, 11]
]
console.log(find(another))
So generally, as a rule, don't loop over arrays and mutate them.
Instead, I recommend using the Array.prototype methods where you can, instead of loops.
A CertainPerformance suggests - you could use filter here instead.
function find(array){
//Assuming array is a 2d array.
return array.map(row => row.filter(v => v%2 ===0));
}
var data = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
var another = [
[2, 2, 7],
[1, 3, 5, 6],
[1, 3, 5, 7, 9, 11]
]
console.log(find(data))
console.log(find(another))
Note that this does return some empty arrays, which maybe you want to keep, or maybe you want to filter again to remove the empty arrays.
Note that, if you're not familiar with it - I'm using the ES6 fat arrow syntax in my answer.

Categories