Why is 0 not removed from the list? - javascript

I was testing out how splice works while iterating through an array, and don't understand why 0 stayed in the list?
var array = [2, 5, 9, 14, 0, 1, 3, 6, 7];
for (var i = 0; i < array.length; i++) {
if (array[i]%2 == 0) {
array.splice(i,1);
}
}
//0 % 2 == 0 is true, and yet
//array = [5, 9, 0, 1, 3, 7]

0 is getting skipped
You are mutating (changing) the array while you're iterating through it. This is a programming no-go.
Let's walk through...
i = 0 and 2 is even and gets spliced, your array is now [5, 9, 14, 0, 1, 3, 6, 7]
i = 1 and we didn't even check 5 which is in index 0 now... we're now checking 9 which is odd, fine
i = 2 and 14 is even and gets spliced, your array is now [5, 9, 0, 1, 3, 6, 7]
i = 3 and 0 gets skipped (as 0 is in index 2 now), 1 is odd, fine
i = 4 is odd fine
i = 5 is even and get spliced
i = 6 is odd fine
What you really want is this...
Array.prototype.filter = function(func) {
var result = new Array();
for (var i = 0; i < this.length; ++i)
if (func(this[i]))
result.push(this[i]);
return result;
}
values = [2, 5, 9, 14, 0, 1, 3, 6, 7];
odd_only = values.filter(function(x) { x % 2 != 0; });

Every time you remove a value from the array, you skip the one that follows it, because the array is reindexed on every splice. You can loop backwards instead:
var array = [2, 5, 9, 14, 0, 1, 3, 6, 7];
for (var i = array.length-1; i >= 0; i--) {
if (array[i]%2 == 0) {
array.splice(i,1);
}
}

It skips the 0 because splice re-indexes the array.
use this:
var array = [2, 5, 9, 14, 0, 1, 3, 6, 7];
for (var i = 0; i < array.length; i++) {
if (array[i]%2 == 0) {
array.splice(i,1);
i = i - 1;
}
}

Related

Loops & Control Flow

When I run this I can't seem to get the rest of the values.
Write a function mergingTripletsAndQuints which takes in two arrays as arguments. This function will return a new array replacing the elements in array1 if they are divisible by 3 or 5. The number should be replaced with the sum of itself added to the element at the corresponding index in array2.
function mergingTripletsAndQuints(array1, array2) {
let result = [];
let ctr = 0;
let x = 0;
for (let i = 0; i < array1.length; i++) {
for (let j = 0; j < array2.length; j++) {
ctr = array1[i] + array2[j];
if (ctr % 3 === 0 || ctr % 5 === 0) {
result.push(ctr);
} else {
return array1[i];
}
}
}
return result;
}
console.log(mergingTripletsAndQuints([1, 2, 3, 4, 5, 15], [1, 3, 6, 7, 8, 9])); // expected log [1, 2, 9, 4, 13, 24]
console.log(mergingTripletsAndQuints([1, 1, 3, 9, 5, 15], [1, 2, 3, 4, 5, 6])); // expected log [1, 1, 6, 13, 10, 21]
It is only logging [1], [1]
I'm not sure, but I suppose there is a typo returning array1[i] in nested loop. I suppose you mean result.push(array1[i]) instead.
I think it should be something like this:
function mergingTripletsAndQuints(array1, array2) {
let result = [];
for (let i = 0; i < array1.length; i++) {
if (array1[i]% 3 === 0 || array1[i]% 5 === 0) {
result.push(array1[i] + array2[i]);
} else {
result.push(array1[i]);
}
}
return result;
}
console.log(mergingTripletsAndQuints([1, 2, 3, 4, 5, 15], [1, 3, 6, 7, 8, 9])); // expected log [1, 2, 9, 4, 13, 24]
console.log(mergingTripletsAndQuints([1, 1, 3, 9, 5, 15], [1, 2, 3, 4, 5, 6])); // expected log [1, 1, 6, 13, 10, 21]
A nested for loop is not necessary, look at this code:
function mergingTripletsAndQuints(array1, array2) {
let sum = [];
for (let i = 0; Math.max(i < array1.length, i < array2.length); i++) {
if (array1[i] % 3 == 0 || array1[i] % 5 == 0) {
sum.push(array1[i] + array2[i])
} else {
sum.push(array1[i])
}
}
return sum;
}

How do I Replace the elements in the Array and assign it zero in javascript?

Write a function squareWave(arr) that takes in the following array: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18], and starts replacing the numbers, one by one, with zeroes, until it reaches a multiple of 5. From that point onwards, start replacing the numbers with 1s, until you reach the next multiple of 5.
Then, from that point onwards, start replacing with 0s again, then 1s again,and so on until you reach the end of the array.
My code is not working Anybody can help me?
let input = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18];
function squareWave(arr) {
let zeros = true;
let output = [];
for (let i = 0; i < arr.length; i++) {
if (arr[i] % 5) {
arr[i] = 0;
} else if (arr[i] !== 5) {
arr[i] = 1;
}
}
console.log(arr)
}
Output should be=[0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1]
You are not keeping track if the current entry should be a 0 or 1. Also, you are not using variables zeros and output
Instead of a boolean, you can keep a 0 or 1 in the variable zeros and flip the value when the mod of 5 equals zero.
if (arr[i] % 5 === 0) {
Then for every iteration write the value of zeros
let input = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18];
function squareWave(arr) {
let zeros = 0;
let output = [];
for (let i = 0; i < arr.length; i++) {
if (arr[i] % 5 === 0) {
zeros = 1 - zeros
}
output[i] = zeros;
}
return output;
}
console.log(squareWave(input));
Or in short:
let input = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18];
let res = input.map(i => Math.abs(Math.floor(i / 5) % 2))
console.log(res)
You can use Array's map function.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
let control = 0;
const list = input.map(value => {
if (value % 5 === 0) {
control = control === 0 ? 1 : 0;
}
return control;
});
console.log(list);
As this is clearly a homework question, I won't give you the answer, but suggest your next steps. You actually almost have the idea of the answer, but you didn't actually implement it.
I'm assuming your current code output looks like [0, 0, 0, 0, 1, 0, 0, 0, 0, 1, ...]
At the beginning of your code you have a boolean variable called zeros. What do you think this boolean is for, and why haven't you used it in your loop?
So your current code is outputting 1 when the value is a multiple of 5, but then it forgets immediately after. How might you fix that?
To replace an element in an array:
Use the indexOf() method to get the index of the element.
Use bracket notation to change the value of the element at the specific index.
The value of the array element will get updated in place.
const arr = ['a', 'b', 'c'];
const index = arr.indexOf('a'); // it will give you 0
if (index !== -1) {
arr[index] = 'z';
}
console.log(arr); // it will give you ['z', 'b', 'c']

latest elements in array not found? codewars kata

I'm solving the following kata:
Given an input of an array of digits, return the array with each digit incremented by its position in the array: the first digit will be incremented by 1, the second digit by 2, etc. Make sure to start counting your positions from 1 (and not 0).
Your result can only contain single digit numbers, so if adding a digit with it's position gives you a multiple-digit number, only the last digit of the number should be returned.
Notes:
return an empty array if your array is empty
arrays will only contain numbers so don't worry about checking that
Examples
[1, 2, 3] --> [2, 4, 6] # [1+1, 2+2, 3+3]
[4, 6, 9, 1, 3] --> [5, 8, 2, 5, 8] # [4+1, 6+2, 9+3, 1+4, 3+5]
# 9+3 = 12 --> 2
My code:
const incrementer = (arr) => {
if (arr === []) {
return []
}
let newArr = []
for (let i = 0; i <= arr.length; i++) {
let result = arr[i] + (i + 1)
newArr.push(result)
if (newArr[i] > 9 ) {
let singleDigit = Number(newArr[i].toString().split('')[1])
newArr.push(singleDigit)
}
}
const filteredArr = newArr.filter(el => el >= 0 && el <= 9)
return filteredArr
}
I can't seem to pass the latest test case, which is the following:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 9, 9, 8]), [2, 4, 6, 8, 0, 2, 4, 6, 8, 9, 0, 1, 2, 2]
I keep getting back the whole correct array up until the second 0, after which the other numbers, 1,2,2 are missing from the solution. What am I doing wrong?
The problem in your code is that the filter only runs at the end, and so when you have done a double push in one iteration (once with the value that has more than one digit, and once with just the last digit), the next iteration will no longer have a correct index for the next value that is being pushed: newArr[i] will not be that value.
It is better to correct the value to one digit before pushing it to your new array.
Moreover, you can make better use of the power of JavaScript:
It has a nice map method for arrays, which is ideal for this purpose
Use modulo arithmetic to get the last digit without having to create a string first
Here is the proposed function:
const incrementer = (arr) => arr.map((val, i) => (val + i + 1) % 10);
console.log(incrementer([1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 9, 9, 8]));
... so if adding a digit with it's position gives you a multiple-digit number, only the last digit of the number should be returned.
So if the number is 12, it expects only 2 to be added to the array.
So your code should be:
if (newArr[i] > 9)
{
newArr[i] = newArr[i] % 10; // remainder of newArr[i] / 10
}
const incrementer = (arr) => {
if (arr.length === 0) { // CHANGE HERE
return [];
}
let newArr = []
for (let i = 0; i <= arr.length; i++) {
let result = arr[i] + (i + 1)
newArr.push(result)
if (newArr[i] > 9 ) {
newArr[i] = newArr[i] % 10; // CHANGE HERE
}
}
const filteredArr = newArr.filter(el => el >= 0 && el <= 9)
return filteredArr
}
console.log(incrementer([2, 4, 6, 8, 0, 2, 4, 6, 8, 9, 0, 1, 2, 2]));
console.log(incrementer([1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 9, 9, 8]));
Please see below code.
const incrementer = arr => {
if (arr === []) {
return [];
}
let newArr = [];
for (let i = 0; i < arr.length; i++) {
let result = arr[i] + (i + 1);
// newArr.push(result);
if (result > 9) {
let singleDigit = Number(result.toString().split("")[1]);
newArr.push(singleDigit);
} else {
newArr.push(result);
}
}
// const filteredArr = newArr.filter(el => el >= 0 && el <= 9);
return newArr;
};
console.log(incrementer([1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 9, 9, 8]))
const incrementer = (arr) => {
if (arr === []) {
return []
}
return arr.map((number, index) => (number + index + 1) % 10);
}
Doing the needed additions in (number + index + 1) and % 10 operation will get the last digit.

Loop backwards Javascript Array

I would like to loop backwards in a array in javascript and then get the index of each element in the array for example if a array has 10 elements and is looped backwards it would log 9, 8, 7, 6, 5, 4, 3, 2, 1, 0. for some werid reason i am getting a bunch of negaitive -1s and im confused why it wont just return the index properly.
here is the code
//Arrays I would like to pass into the function
const valid1 = [4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8];
const invalid1 = [4, 5, 3, 2, 7, 7, 8, 7, 7, 1, 0, 9, 1, 7, 9, 5];
function validateCred(arr) {
let sum = 0;
for (let i = arr.length - 1; i >= 0; i--) {
console.log(arr.indexOf(i));
}
}
console.log(validateCred(valid1));
why -1s?
It is because of arr.indexOf(i) when the loop starts i=15 so:
arr.indexOf(15) will return -1 because you don't have a 15 in your array.
next i=14 same as above.
.
.
.
i=9 then it will find the element at index 3.
As UnholySheep explains above, Array.indexOf(i) gives you the index of the first occurrence of the value represented by i in the array. Here is some code to help you debug:
function validateCred(arr) {
let sum = 0
for (let i = arr.length - 1; i >= 0; i--) {
console.log(i) // log the index
console.log(arr[i]) // log the value
}
}

Have a big array of integers need to return an array that has 1 added to the value represented by the array

It is for a studying purpose. Have a big array of integers need to return an array that has 1 added to the value represented by the array.
Tried to convert the array into an integer, but after using
parseInt('9223372036854775807', 10) received 9223372036854776000, instead of 9223372036854775807
What is going wrong here?
var arr = [ 9, 2, 2, 3, 3, 7, 2, 0, 3, 6, 8, 5, 4, 7, 7, 5, 8, 0, 7 ];
function upArray(arr){
var numb = arr.join('');
numb = parseInt(numb, 10);
var result = numb + 1;
console.log(result);
result = result.toString(10).split('').map(Number);
return result;
}
You are exceeding the capacity of JavaScript's number type
IEEE-754 double-precision floating point (the kind of number JavaScript uses) can't precisely represent all numbers
Beyond Number.MAX_SAFE_INTEGER + 1 (9007199254740992), the IEEE-754 floating-point format can no longer represent every consecutive integer
also you dont need to use a second argument to parseInt unless you are looking to use a different base than decimal
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt
If you use the code with an array of numbers that when joined is within this limit your code will work
var arr = [ 9, 2, 2, 3, 3, 7, 2, 0, 3, 6, 8, 5 ];
function upArray(arr){
var numb = arr.join('');
numb = parseInt(numb);
var result = numb + 1;
console.log(result)
result = result.toString(10).split('').map(Number);
return result;
}
console.log(upArray(arr))
As you're exceeding the MAX_SAFE_INTEGER.
If you just want to display you can go this way
var arr = [ 9, 2, 2, 3, 3, 7, 2, 0, 3, 6, 8, 5, 4, 7, 7, 5, 8, 0, 7 ];
function addone(arr){
let carry = 0;
for(let i=arr.length-1; i>=0; i--){
if(i === arr.length-1) {
if( arr[i]+1 > 9){
arr[i] = 10-(arr[i] + 1);
carry = 1;
} else {
arr[i] +=1;
carry= 0;
}
}
if( i !== arr.length-1 ){
if( carry === 0) break;
if( arr[i]+1+carry > 9){
arr[i] = 10-(arr[i] + carry);
carry = 1;
} else {
arr[i] +=carry;
carry= 0;
}
}
}
if(carry === 1)
arr.unshift(1)
return arr;
}
console.log(addone(arr).join(''))
console.log(addone([1,2,9]).join(''))
console.log(addone([9,9,9]).join(''))
The value is going beyond the max number value.
Here is recursive appproch for the problem:
function upArray(arr, lastIndex){
if(lastIndex == undefined){
lastIndex = arr.length - 1;
}
if(lastIndex < 0){
return;
}
if(arr[lastIndex] == 9){
arr[lastIndex] = 0;
upArray(arr, lastIndex - 1);
}
else {
arr[lastIndex] = arr[lastIndex] + 1;
}
return arr;
}
var arr = [ 9, 2, 2, 3, 3, 7, 2, 0, 3, 6, 8, 5, 4, 7, 7, 5, 8, 0, 9];
var result = upArray(arr);
console.log(result);
Another solution so you can choice =)
var arr = [9,9,9];//[ 9, 2, 2, 3, 3, 7, 2, 0, 3, 6, 8, 5, 4, 7, 7, 5, 8, 0, 7 ];
var i = arr.length;
var append = true;
while(append){
if(--i < 0){
arr.unshift(1);
break;
}
var v = arr[i];
if(++v >= 10)
v -= 10;
else
append = false;
arr[i] = v;
}
var r = arr.join('');
console.log(r);
it means the maximum range for an Intiger number has reached, here is a link
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER
to solve this split the array value and add one to it and then combine then back and display the entire array as a String (don't parse it).
function upArray(arr){
var temp = arr;
var len = arr.length;
var temp2 = arr;
temp2 = temp2.slice(0,len/2).join('');
temp2 = parseInt(temp2);
temp = temp.slice(len/2).join('');
numb = parseInt(temp) +1;
if(numb.toString().length > (len/2 + len%2))
{
numb = numb.toString().slice(1);
temp2++;
}
var result = temp2.toString() + numb.toString();
console.log(result);
result = result.split('').map(Number);
return result;
}
hope it helps and have pass through every test...
As everybody would agree that the issue here is having a value that is exceeding the capacity of JavaScript's number type, we can expect that there'll be proposed workarounds like having to split the array into multiple array and work from there.
We can actually solve this on another approach. Since your representation of a number is splitting it into single digits stored as an array, and you want to perform a simple addition on it, we can observe a representation of a simple/elementary addition. The one where we add a value digit by digit from the bottom and make use of the "Carry Over" concept. We can actually do it that way.
It will look somewhat like this (A bit longer code for readability):
var x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9];
var y = [9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9];
var add1 = (arr) => {
var hasCarryOver = true;
for (var index = arr.length - 1; index >= 0; index--) {
if (!hasCarryOver) {
break;
}
if (arr[index] < 9) {
arr[index] = arr[index] + 1;
hasCarryOver = false;
} else {
arr[index] = 0;
}
}
if (hasCarryOver) {
arr.unshift(1);
}
return arr;
};
x = add1(x);
y = add1(y);
console.log('result x add 1', x);
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 9, 0]
console.log('result y add 1', y);
// [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

Categories

Resources