Function that removes every second element [duplicate] - javascript

This question already has answers here:
Remove items from array with splice in for loop [duplicate]
(5 answers)
Closed 2 years ago.
I want to write a function that removes every second element given that the array is longer than length 2. For instance:
removeEveryOther([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) returns [1, 3, 5, 7, 9]);
removeEveryOther([[1, 2]]) returns [[1, 2]])
Here is my try:
function removeEveryOther(arr){
for (i=0; i < arr.length; i++) {
if (arr.length>2) {
arr.splice((2*i), 1);
}
}
return arr
}
When invoked the function:
removeEveryOther(['1', '2', '3', '4', '5', '6', '7']) returns [ '2', '3', '5', '6' ]
Not sure what I'm doing wrong though, thanks for reading or even helping me out. Have a nice day!

You can use filter. And move the check up to the top:
function removeEveryOther(arr){
if (arr.length <= 2) {
return arr
}
return arr.filter((a,i) => i%2 == 0);
}

You should not mutate the original array and rather create a new one.
function removeEveryOther(arr){
if (arr.length > 2) {
return arr.filter((item, index) => index % 2 === 0);
} else {
return arr;
}
}

you can do this:
let removeEvery2 = (arr) => {
if(arr.length > 2) {
return arr.filter((el, i) => i % 2 === 0)
}
return arr
}

You could loop from the end, because with splicing from start all following indices are gone.
function removeEveryOther(array) {
if (array.length < 3) return array;
let i = Math.floor(array.length / 2) * 2 + 1;
while (i > 0) {
array.splice(i, 1);
i -= 2;
}
return array;
}
console.log(removeEveryOther([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])); // [1, 3, 5, 7, 9]
console.log(removeEveryOther([1, 2]));

Use a simple for loop. Start at index 1 instead of 0 and increment i by 2 instead of 1.
function removeEveryOther(arr){
if(arr.length <= 2) return arr;
for(let i = 1; i < arr.length; i +=2){
arr.splice(i, 1);
}
return arr;
}
console.log(removeEveryOther([1, 2, 3, 4, 5, 6, 7, 8]));
console.log(removeEveryOther([1, 2]))

Try this function, I kept it very simple for your understanding and very near to what you wrote in the question
function removeEveryOther(arr)
{
if(arr.length <= 2)
return arr;
var arr_ret = [];
for (i=0; i < arr.length; i+=2)
{
arr_ret.push(arr[i])
}
return arr_ret
}

Related

how to remove following arguments after the array

destroyer(array1, some arguments) function should return the array1 excluding the arguments. I found some working ways like return arr = arr.filter(val => !rem.includes(val)); but I need to fix this code and find out why this code giving an incorrect result. It supposed to be [1]
function destroyer(arr, ...rem) {
for(let i = 0; i < arr.length; i++) {
if (rem.includes(arr[i])) {
arr.splice(i, 1);
};
};
return arr;
}
console.log(destroyer([3, 5, 1, 2, 2], 2, 3, 5));
function destroyer(arr, ...rem) {
const itemsToRemove = new Set(rem);
return arr.reduce((acc, curr) => itemsToRemove.has(curr) ? acc : [...acc, curr] ,[])
}
console.log(destroyer([3, 5, 1, 2, 2], 2, 3, 5));
The problem is the call of the function Array.prototype.splice within the for loop, this function is mutating the array and basically affects the indexes of the array, therefore the current index i is no longer valid.
To work around this, you can loop in a backward direction, this way we can mutate the array, and the current index is not affected.
One more thing, your approach is mutating the array, a better approach would be by using the function Array.prototype.filter along with the function Array.prototype.includes, see other answers.
function destroyer(arr, ...rem) {
for(let i = arr.length; i >= 0; i--) {
if (rem.includes(arr[i])) {
arr.splice(i, 1);
};
};
return arr;
}
console.log(destroyer([3, 5, 1, 2, 2], 2, 3, 5));
Or you can do it like this:
const destroyer=(arr, ...rem)=>arr.filter(v=>!rem.includes(v));
console.log(destroyer([3, 5, 1, 2, 2], 2, 3, 5));

Add every n items in an array

I have an array like so:
[5, 12, 43, 65, 34 ...]
Just a normal array of numbers.
What I wan't to do is write a function group(n, arr) which adds every n numbers in the array.
For example if I call group(2, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]) it should return
[
3 //1+2,
7 //3+4,
11 //5+6,
15 //7+8,
19 //9+10,
11 //whatever remains
]
I haven't tried anything yet, I will soon update with what I can.
You can use .reduce as follows:
function group(n, arr) {
// initialize array to be returned
let res = [];
// validate n
if(n > 0 && n <= arr.length) {
// iterate over arr while updating acc
res = arr.reduce((acc, num, index) => {
// if the current index has no remainder with n, add a new number
if(index%n === 0) acc.push(num);
// else update the last added number to the array
else acc[acc.length-1] += num;
// return acc in each iteration
return acc;
}, []);
}
return res;
}
console.log( group(2, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]) );
This approach features two loops, one for checking the outer index and anoter for iterating the wanted count of items for summing.
function group(n, array) {
const result = [];
let i = 0;
while (i < array.length) {
let sum = 0;
for (let j = 0; j < n && i + j < array.length; j++) {
sum += array[i + j];
}
result.push(sum);
i += n;
}
return result;
}
console.log(group(2, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]));
You could use Array.from to create the result array and then use its mapper to make the sums. These sums can be made by using reduce on the relevant slice of the array .
This is a functional programming solution:
const group = (step, arr) =>
Array.from({length: Math.ceil(arr.length/step)}, (_, i) =>
arr.slice(i*step, (i+1)*step).reduce((a, b) => a+b)
);
console.log(group(2, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]));

Javascript Binary Search algorithm unable to find number in the list

The following code seems to be unable to find the number in the list. Why might this be?
Trying this with the number to search for as '9' and the array of numbers consisting of numbers between 1-10 inclusively.
array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
count = 0;
function binarySearch(array, number) {
mid = Math.floor(array.length / 2);
if (number === array[mid]) {
return count;
}
else if (number < array[mid] && array.length > 1) {
count++;
arrayFirst = array.splice(0, array[mid]);
console.log("Tried: ", array[mid])
console.log(arrayFirst);
return binarySearch(arrayFirst, number);
}
else if (number > array[mid] && array.length > 1) {
count++;
arraySecond = array.splice(array[mid], array.length);
console.log("Tried: ", array[mid])
console.log(arraySecond);
return binarySearch(arraySecond, number);
}
else {
return 'number doesnt exist';
}
}
console.log(binarySearch(array, 4));
The code is now struggling with finding the number 10
New Edit:
array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,13,14,15,16,17,18,19,20];
count = 0;
function binarySearch(array, number) {
mid = Math.floor(array.length/ 2);
if (number === array[mid]) {
return count;
}
else if (number < array[mid] && array.length > 1) {
count++;
arrayFirst = array.splice(0, mid);
console.log("Tried: ", array[mid])
console.log(arrayFirst);
return binarySearch(arrayFirst, number);
}
else if (number > array[mid] && array.length > 1) {
count++;
arraySecond = array.splice(array[mid], mid);
console.log("Tried: ", array[mid])
console.log(arraySecond);
return binarySearch(arraySecond, number);
}
else {
return 'number doesnt exist';
}
}
console.log(binarySearch(array, 10));
This:
array = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10;
is not an array, it's interpreted as a list of initialization, like this:
array = 1, x = 2, y = 3...;
and so your array is just 1, and not the entire list. Also keep in mind that it is Not Recommended to declare a variable without var keyword. It can accidently overwrite an existing global variable. Instead you should use var, let or const based on the use of that variable
Instead, this should be your array:
array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
Few pointers here:
Your condition includes an undefined variable arr. You've been using array.
Your array must be array = [1,2,3]
I would suggest to instantiate your variables arrayFirst, mid, arraySecond as const const mid = ... so they are block scoped and not global vars
Edit: Looks like you've modified your arr condition. Please avoid edits as it makes answers irrelevant.
You are using array.splice(0, array[mid])
array[mid] is the value in the array and you need the quantity of elements to subtract array.splice(0, mid) splice docs
also index start from 0 so your array[mid] is taking the 6th element and not the middle.
Some changes:
Take counting inside of the function by returning either one or zero or one plus the result of the call with a sub array.
Check length in advance (spelling matters ... arr) and return zero for unrachable values.
Use Array#slice instead of Array#splice (prevent mutation) and take the index, not the value of the item.
Finally return one plus the count of left or right side.
function binarySearch(array, number) {
console.log(...array);
var mid = Math.floor(array.length / 2);
if (number === array[mid]) return 1;
if (array.length <= 1) return 0;
return number < array[mid]
? 1 + binarySearch(array.slice(0, mid), number)
: 1 + binarySearch(array.slice(mid), number);
}
console.log('count:', binarySearch([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 4));

Reverse numbers in function without using ".reverse" method in Javascript

function revertNumbers(...numberArray) {
let rev = [];
for(let i = 0; i <numberArray.length; i++)
{
rev.push(numberArray[i])
}
return rev.reverse();
}
console.log("revertNumbers", revertNumbers(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) === "9,8,7,6,5,4,3,2,1,0");
Can you please show me the how to reverse number in this code that the statement will be true? Also without using .reverse method. Is it possible to make it in another for loop by just changing this statement:
(let i = 0; i <numberArray.length; i++)
You just need to reverse the direction of your loop. Means start i with last index and then gradually decrease it to 0
function revertNumbers(...numberArray) {
let rev = [];
for(let i = numberArray.length - 1; i >= 0; i--)
{
rev.push(numberArray[i])
}
return rev.join(",")
}
console.log("revertNumbers", revertNumbers(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) === "9,8,7,6,5,4,3,2,1,0");
This is also a good use case of reduceRight()
const revertNumbers = (...arr) => arr.reduceRight((ac, a) => ([...ac, a]), []).join(',')
console.log("revertNumbers", revertNumbers(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) === "9,8,7,6,5,4,3,2,1,0");
Here is a solution that manipulates the array in place, and only has to traverse half of the original array in order to reverse it. This ekes out some modest performance gains compared to other answers in this thread (my function narrowly beats out or matches the speed of even the native reverse method in ops/sec), but micro-optimizations are largely irrelevant for this problem unless you are talking about a truly massive list of numbers.
Nonetheless, here is my answer:
const revNums = (...numArray) => {
for (
let arrLen = numArray.length,
breakPoint = ((arrLen / 2)|0) - 1,
i = arrLen,
k = 0,
temp;
--i !== breakPoint;
++k
) {
temp = numArray[i];
numArray[i] = numArray[k];
numArray[k] = temp;
}
return numArray.join(',');
};
You could reduce the original array and unshift each element onto the new array.
function revertNumbers(...numberArray) {
return numberArray.reduce((r, e) => { r.unshift(e); return r }, []).join(',')
}
console.log("revertNumbers", revertNumbers(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) === "9,8,7,6,5,4,3,2,1,0")
If you don't want to unshift, you can concat in reverse.
function revertNumbers(...numberArray) {
return numberArray.reduce((r, e, i, a) => r.concat(a[a.length - i - 1]), []).join(',')
}
console.log("revertNumbers", revertNumbers(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) === "9,8,7,6,5,4,3,2,1,0")
You could take a value and the rest of the arguments and use a recursive approach to get a reversed array of arguments.
function revertNumbers(v, ...rest) {
return rest.length
? [...revertNumbers(...rest), v]
: [v];
}
console.log(revertNumbers(0, 1, 2, 3, 4, 5, 6, 7, 8, 9));
It is to ask how many solutions can be possible ?
here are 3 of them...
"use strict";
const targetString = '9,8,7,6,5,4,3,2,1,0'
;
function soluce_1(...numberArray)
{
const rev = [];
for( let i=numberArray.length;i--;) { rev.push(numberArray[i]) }
return rev.join(',')
}
function soluce_2(...numberArray)
{
const rev = [];
let pos = numberArray.length;
for(let N in numberArray) { rev[--pos] = N }
return rev.join(",")
}
function soluce_3(...numberArray)
{
const rev = [];
while(numberArray.length) { rev.push(numberArray.pop()) }
return rev.join(',')
}
console.log('soluce_1 ->', (soluce_1(0,1,2,3,4,5,6,7,8,9)===targetString) );
console.log('soluce_2 ->', (soluce_2(0,1,2,3,4,5,6,7,8,9)===targetString) );
console.log('soluce_3 ->', (soluce_3(0,1,2,3,4,5,6,7,8,9)===targetString) );
And yes, I code in Whitesmiths style, please respect this (the reason for the downVote for correct answers ?)
https://en.wikipedia.org/wiki/Indentation_style#Whitesmiths_style
You might reverse like this:
function reverse(...a) {
const h = a.length >> 1, l = a.length-1;
for (let i = 0; i < h; ++i) [a[i], a[l-i]] = [a[l-i], a[i]];
return a;
}
console.log(reverse(0, 1, 2, 3, 4, 5, 6, 7, 8, 9).join(','));

Javascript loop an array to find numbers divisible by 3

I am needing to find the correct way to have javascript loop through an array, find all numbers that are divisible by 3, and push those numbers into a new array.
Here is what I have so far..
var array = [],
threes = [];
function loveTheThrees(array) {
for (i = 0, len = array.length; i < len; i++) {
threes = array.push(i % 3);
}
return threes;
}
So if we pass through an array of [1, 2, 3, 4, 5, 6] through the function, it would push out the numbers 3 and 6 into the "threes" array. Hopefully this makes sense.
You can use Array#filter for this task.
filter() calls a provided callback function once for each element in an array, and constructs a new array of all the values for which callback returns a true value or a value that coerces to true. callback is invoked only for indexes of the array which have assigned values; it is not invoked for indexes which have been deleted or which have never been assigned values. Array elements which do not pass the callback test are simply skipped, and are not included in the new array.
function loveTheThrees(array) {
return array.filter(function (a) {
return !(a % 3);
});
}
document.write('<pre>' + JSON.stringify(loveTheThrees([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]), 0, 4) + '</pre>');
console.log([1, 2, 3, 4, 5, 6, 7].filter(function(a){return a%3===0;}));
Array.filter() iterates over array and move current object to another array if callback returns true. In this case I have written a callback which returns true if it is divisible by three so only those items will be added to different array
var array = [],
three = [];
function loveTheThrees(array) {
for (i = 0, len = array.length; i < len; i++) {
if(array[i] % 3 == 0){
three.push(array[i]);
}
}
return three;
}
Using Filter like suggested by Nina is defiantly the better way to do this. However Im assuming you are a beginner and may not understand callbacks yet, In this case this function will work:
function loveTheThrees(collection){
var newArray = []
for (var i =0; i< collection.length;i++){
if (myArray[i] % 3 === 0){
newArray.push(collection[i])
}
}
return newArray;
}
loveTheThrees=(arr)=>arr.filter(el=>Boolean(parseFloat(el)) && isFinite(el) && !Boolean(el%3))
es6 version + skipping non numbers
loveTheThrees([null,undefined,'haha',100,3,6])
Result: [3,6]
Check if the number is divisible by 3 if so then add it to array. Try this
function loveTheThrees(array) {
for (i = 0, len = array.length; i < len; i++) {
if(array[i] % 3 == 0){
three.push(array[I]);
}
}
var originalArray = [1, 2, 3, 4, 5, 6, 7, 8, 9];
function loveTheThrees(array1) {
var threes = [];
for (var i = 0; i < array1.length; i++) {
if (array1[i] % 3 === 0) {
threes.push(array1[i]);
}
}
return threes;
}
loveTheThrees(originalArray);
In ES6:
const arr = [1, 33, 54, 30, 11, 203, 323, 100, 9];
// This single line function allow you to do it:
const isDivisibleBy3 = arr => arr.filter(val => val % 3 == 0);
console.log(isDivisibleBy3(arr));
// The console output is [ 33, 54, 30, 9 ]

Categories

Resources