Any help will be very appreciated... I am trying to figure out how to nest loops inside of a function. If I input this into the console...
var i, arr = [1, 2, 3, 4, 5, 6];
var remove = [];
for (i = 0; i < arr.length; i++) {
if (Number(arr[i]) != i % 2) {
remove.push(arr[i]);
arr.splice(i, 1);
}
}
console.log(remove);
it returns with the desired array, removing all the even numbers from arr. But, if I wrap it in a function, it is undefined...
var i, arr = [1, 2, 3, 4, 5, 6];
var remove = [];
function reject() {
for (i = 0; i < arr.length; i++) {
if (Number(arr[i]) != i % 2) {
remove.push(arr[i]);
arr.splice(i, 1);
}
}
};
console.log(remove);
What am I doing wrong?
When code is not in a function, every line in the script is executed as it is interpreted (roughly speaking).
If you wrap some code inside a function, you have to call the function for it's effects to be applied.
Also, you should try and keep some variables inside the function, for example your i counter could be local to the function instead of the global scope of the function.
Therefore, use the function name to apply it's effects:
var arr = [1, 2, 3, 4, 5, 6];
var remove = [];
function reject() {
var i;
for (i = 0; i < arr.length; i++) {
if (Number(arr[i]) != i % 2) {
remove.push(arr[i]);
arr.splice(i, 1);
}
}
};
reject(); // Difference here, we're calling the function.
console.log(remove);
You need to call the function before you try to log the value of remove.
var i, arr = [1, 2, 3, 4, 5, 6], remove = [];
function reject() {
for (i = 0; i < arr.length; i++) {
if (Number(arr[i]) != i % 2) {
remove.push(arr[i]);
arr.splice(i, 1);
}
}
};
reject();
console.log(remove);
Others have already answered what the problem is, you have to call the function. However, if you improve it not to use globals, it may be more obvious that you need to call it and is much cleaner code.
var arr = [1,2,3,4,5];
function reject(input) {
var output = [];
for (var i = 0; i < input.length; i++) {
if (Number(arr[i]) != i % 2) {
output.push(arr[i]);
input.splice(i, 1);
}
}
return output;
};
var remove = reject(arr);
Related
I am attempting to remove specific elements from an array that is found in another array. My array is returning unchanged. My assumption is my condition in the if statement is not correct, however, I can't find a clear explanation online as to what this is supposed to be exactly. Any help is greatly appreciated.
Trying to remove ...args from array
<script>
removeFromArray = function(array, ...args) {
let removalItems = Array.from(args);
for (i = 0; i < removalItems.length; i++) {
if (array === removalItems[i]) {
array.splice(i, 1);
} else {
i++
}
}
// console.log(array);
return array;
}
removeFromArray([1, 2, 3, 4], 3, 2)
</script>
```
The problem in your code is that you are making one loop through removeFromArray but you are not looping through your array to check every element in array against removefromarray you have to use nested loop
removeFromArray = function(array, ...args) {
let removalItems = Array.from(args);
for (i = 0; i < array.length; i++) {
for (j = 0; j < removalItems.length; j++) {
if (array[i] === removalItems[j]) {
array.splice(i, 1);
i--
}
else continue
}
}
return array
}
console.log(removeFromArray([1, 2, 3, 4], 3, 2))
A different approach is to use filter
removeFromArray = function(array, ...args) {
let removalItems = Array.from(args);
return array.filter(x=>!removalItems.some(y=>x==y))
}
console.log(removeFromArray([1, 2, 3, 4], 3, 2));
Using filter() would simplify this and would not mutate original array
const removeFromArray = (array, ...args) => {
let removalItems = new Set(args);
return array.filter(e => !removalItems.has(e));
}
console.log(removeFromArray([1, 2, 3, 4], 3, 2))
You have few errors, wont work if they are not in same position and also as you remove the item with slice you need to decrement i otherwise you will skip items
const removeFromArray = (array, ...removalItems) => {
for (i = 0; i < array.length; i++) {
if (removalItems.includes(array[i])) {
array.splice(i, 1);
i--;
}
}
return array;
}
But filter is much clenaner
const removeFromArray = (array, ...removalItems) => array.filter(x => !removalItems.includes(x))
You are treating array as if it has single object.
Loop over the array and using includes method check if that element if present in the removalItems array . If yes splice , else increment.
removeFromArray = function(array, ...args) {
let removalItems = Array.from(args);
for (i = 0; i < array.length; i++) {
if (removalItems.includes(array[i])) {
array.splice(i, 1);
i--;
}
}
// console.log(array);
return array;
}
console.log(removeFromArray([1, 2, 3, 4], 3, 2));
Here is the another solution , without splicing the array while iterating over it.
removeFromArray = function(array, ...args) {
let removalItems = Array.from(args);
let result = [];
for (i = 0; i < array.length; i++) {
if (!removalItems.includes(array[i])) {
result.push(array[i]);
}
}
// console.log(array);
return result;
}
console.log(removeFromArray([1, 2, 3, 4], 3, 2));
In your for loop you have to
for (let j=0; j<array.length; j++)
if (array[j]===removalItems[i])
...the rest is the same
Using your same code pattern, you have 3 mistakes:
let removalItems = Array.from(args);
for (i = 0; i < array.length; i++) {
for (j = 0; j < removalItems.length; j++) {
if (array[i] === removalItems[j]) {
array.splice(i, 1);
i--
}
}
}
Furthermore you need another for loop to iterate through all the options.
This code has ended up being slightly inefficient but it'll do for most applications. I removed the else statement because you are already incrememnting i every time you loop.
I canĀ“t understand in this particular script how reduce works. I though that reduce always treats first argument as a acumulator, but in this ocassion the var result = [] seems to be the acumulator or maybe I am wrong. Initially I understood that fist argument of function symDiff (arrayOne) should be the accumulator for reduce method.
function sym() {
var args = [];
for (var i = 0; i < arguments.length; i++) {
args.push(arguments[i]);
}
function symDiff(arrayOne, arrayTwo) {
var result = [];
arrayOne.forEach(function(item) {
if (arrayTwo.indexOf(item) < 0 && result.indexOf(item) < 0) {
result.push(item);
}
});
arrayTwo.forEach(function(item) {
if (arrayOne.indexOf(item) < 0 && result.indexOf(item) < 0) {
result.push(item);
}
});
return result;
}
// Apply reduce method to args array, using the symDiff function
return args.reduce(symDiff);
}
sym([1, 2, 3], [5, 2, 1, 4]);
The task is to build a function where it receives an array and a number that will work as a limit. The thing is that it should return an array with the resulting booleans like this:(i.e. [true, false, false]). But I can't figure out how.
I tried using a for loop to stuff an empty array, but it returns just false.
function aperturas(arrayDeIngresosSemanales, cantMinEst) {
for (var i = 0; i < arrayDeIngresosSemanales.length; i++) {
var a = 0;
var arr = arrayDeIngresosSemanales[i];
for (var j = 0; j < arr.length; j++) {
if (arr[j] <= 0) {
a = a + 1;
}
}
if (a >= cantMinEst) {
return true;
} else {
return false;
}
}
}
aperturas([0, 0, 3, 0], [1, 2, 4, 5], [0, 0, -1], 3);
return breaks out of the function - have a result array instead:
function aperturas(arrayDeIngresosSemanales, cantMinEst) {
let result = [];
// ...
if (a >= cantMinEst) {
result.push(true);
}
result.push(false);
}
// ...
return result;
}
You could even remove the if statement:
result.push(a >= cantMinEst);
You shouldn't return immediately after evaluating an array element.
Create a result array and push result of each array's evaluation and return the result.
Also, you aren't calling the function properly. First argument is an array of arrays, you have to call it like aperturas([[0, 0, 3, 0], [1, 2, 4, 5], [0, 0, -1]], 3)
function aperturas(arrayDeIngresosSemanales, cantMinEst) {
// Create an array to store the result.
var result = [];
for (var i = 0; i < arrayDeIngresosSemanales.length; i++) {
var a = 0;
var arr = arrayDeIngresosSemanales[i];
for (var j = 0; j < arr.length; j++) {
if (arr[j] <= 0) {
a = a + 1;
}
}
// Now compare with limit after iterating completely over the array.
if (a >= cantMinEst) {
result.push(true);
} else {
result.push(false);
}
}
// After iterating over all the arrays, return the result.
return result;
}
console.log(aperturas([[0, 0, 3, 0], [1, 2, 4, 5], [0, 0, -1]], 3));
Or, alternatively if you want to use a more semantic JS feature than the for loop, you could keep the return statements but use the map function instead. That would look something like this:
arrayDeIngresosSemanales.map((arr) => {
var a = 0;
for (var j = 0; j < arr.length; j++) {
if (arr[j] <= 0) {
a = a + 1;
}
}
if (a >= cantMinEst) {
return true;
} else {
return false;
}
})
By that same token, you could also replace the inner for loop with a reduce, but that will be left as an exercise for the reader.
I am trying to write a function that will make a string of random numbers appear one after the other inside an html element. See the function below:
document.getElementById("button-1").onclick = function () {
var numbersArray = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var newNumbersArray = [];
function createNewArray (array) {
for (i=0;i<50;i++) {
array.push(numbersArray[Math.floor(Math.random()*11)]);
}
return array;
}
for (j = 0; j < newNumbersArray.length; j++) {
document.getElementById("number-display").innerHTML = newNumbersArray[j];
}
}
The first part of the function takes an array of numbers 0-10 and creates a new array 50 elements long made up of random numbers from the variable numbersArray. Then the function is supposed to display each number one after the other on the html page (note that I am aware this would happen so fast that you would only see the last number. I plan to later add a timer, right now I am just trying to get the basic functionality). However, when I click the button the html page, absolutely nothing happens. What am I missing?
Many thanks for your help. I am a newbie (probably quite obvious).
The problem is that you never called createNewArray
document.getElementById("button-1").onclick = function () {
var numbersArray = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var newNumbersArray;
function createNewArray (array) {
for (i=0;i<50;i++) {
array.push(numbersArray[Math.floor(Math.random()*11)]);
}
return array;
}
// this is required
newNumbersArray = createNewArray([]);
for (j = 0; j < newNumbersArray.length; j++) {
document.getElementById("number-display").innerHTML = newNumbersArray[j];
}
}
<div id='number-display'></div>
<button id="button-1">Action</button>
You're not calling createNewArray(), maybe you're missing:
newNumbersArray = createNewArray(numbersArray)
Also, this looks weird because you're overwritting the value multiple times:
for (j = 0; j < newNumbersArray.length; j++) {
document.getElementById("number-display").innerHTML = newNumbersArray[j];
}
You could do:
document.getElementById("number-display").innerHTML = '';
for (j = 0; j < newNumbersArray.length; j++) {
document.getElementById("number-display").innerHTML += newNumbersArray[j] + ",";
}
But there is an easier way:
document.getElementById("number-display").innerHTML = newNumbersArray[j].join(',');
The issue that I found in your code is that you are defining a function called createNewArray but you never use it.
The solution should be:
createNewArray(newNumbersArray)
However, I'd recommend you to do the following:
document.getElementById("button-1").onclick = function () {
var newNumbersArray;
function createNewArray () {
// instead of passing a parameter which will be modified,
// you can create a variable inside your function and return it
var array = [];
for (i=0;i<50;i++) {
// array.push(numbersArray[Math.floor(Math.random()*11)])
// the line above is practically the same as the line bellow
array.push(Math.floor(Math.random()*11));
}
return array;
}
// so you can use it in this way
newNumbersArray = createNewArray();
for (j = 0; j < newNumbersArray.length; j++) {
document.getElementById("number-display").innerHTML = newNumbersArray[j];
}
}
<div id="number-display"></div>
<button id="button-1">Action</button>
Below is code for a function that returns all permutations of a given array.
function getAllPerms(s) {
var perms = [];
if (s.length === 1) {
perms.push(s);
} else {
for (var i = 0; i < s.length; i++) {
var sub = s.slice(0);
sub.splice(i, 1);
var sp = getAllPerms(sub);
for (var o = 0; o < sp.length; o++) {
sp[o].unshift(s[i]);
perms.push(sp[o]);
}
}
}
return perms;
}
console.log(getAllPerms([1,2])); // result is [[1, 2], [2, 1]]
however if i don't make a copy of the array and splice the original array I don't get the same output, and I have been racking my brain to understand why? To me, it seems as though it should work either way. Below is the code with changes to the original array.
function getAllPerms(s) {
var perms = [];
var len = s.length
if (s.length === 1) {
perms.push(s);
} else {
for (var i = 0; i < len; i++) {
var digit = s[i];
s.splice(i, 1);
var sp = getAllPerms(s);
for (var o = 0; o < sp.length; o++) {
sp[o].unshift(digit);
perms.push(sp[o]);
}
}
}
return perms;
}
console.log(getAllPerms([1,2])); // result is [[2, 1], [2, 1]]
For the first set of code I get the correct result,[[1, 2], [2, 1]], but for the second bit of code I get something strange, [[2, 1], [2, 1]]. Cannot for the life of me figure out what is going on.
When you run the code that changes the original array, you're actually modifying the input array sto be first [1,2] then [2,1], and your return array is just the original array s multiple times, so modifying s to become the second element also modifies it as the first element.
You can see the effect more simply by running the following:
var x = [1,2]
var p = []
p.push(x)
x[0] = 2
x[1] = 1
p.push(x)
Observe how x and p change after each line.