I would like to understand why my console.log outputs the elements which have been placed before some().
function isBiggerThan10(element, index, array) {
console.log(element);
return element > 10;
}
[2, 5, 8, 1, 4].some(isBiggerThan10);
From my understanding, the elements should be outputted if they are given as parameters of isBiggerThan10(). I guess this is because of the array function some(). If so, how can I write a similar code like what some() does? The goal is to output all elements of the array in the function myElements(). myElements should be a parameter of the function test().
This is what I have tried:
Array.prototype.test = function(i) {
console.log(i);
};
function myElements(element) {
console.log(element);
}
[2, 5, 8, 1, 4].test(myElements);
But it seems like that I don't understand the logic behind of it.
some() method is used to check a condition on all array elements (or specified elements) and returns true if any of the array elements matches the condition and returns false if all array elements do not match the condition.
In case why all the element is being printed?, It is the fact that when you call the function you have console logged it, that's it .
so if you want to output all the numbers greater than 10 you can use the filter method.
function isBiggerThan10(element, index, array) {
return element > 10;
}
console.log([2, 5, 8, 1, 4].filter(isBiggerThan10))
The syntax of Array.prototype.some() function specifies that you call some() over an array, and it takes for parameters a callback function (function isBiggerThan10() in your snippet), which itself takes one argument and 3 other optional ones. The main argument required is element which, is the value of each element that you iterate over from the array that calls some(). You can check the docs here.
Syntax
arr.some(callback(element[, index[, array]])[, thisArg])
Parameters
callback: A function to test for each element, taking three arguments:
element: The current element being processed in the array.
TLDR: some() iterates through each element of the array until condition is met, and the element argument in the callback function holds the value of the current element that is being iterated.
some function calls your isBiggerThan10 function for every element of the array. That's why all array elements are printed to console. Please refer https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some for more details
Related
Here is piece of code I am trying to fully understand:
const words = ['chair', 'music', 'pillow', 'brick', 'pen', 'door'];
const shortWords = words.filter(word => {
return word.length < 6;
});
My current assumption is that shortWords is a function that is having another function passed in as a parameter.
So shortWords is to use .filter on the words array. The argument (which is also a function?) thats passed into the shortWords function is supposed to return all words with a length less than 6 letters from the array.
Is my understaning correct or am I missing something?
Yes, you are correct except the fact that shortWords is a variable that stores an array returned by .filter function.
The types of words is an array.
const words = ['chair', 'music', 'pillow', 'brick', 'pen', 'door'];
Array.filter is a method/function that allows you to loop through the array. As the name suggests, it is used to filter the array and create a new array.
Array.filter accepts a function as a parameter. In your provided snippet you have passed an arrow function as a parameter inside the filter method.
This is similar to the following code with simple function:
function filterFunctionAsParam(word) {
return word.length < 6;
}
const shortWords = words.filter(filterFunctionAsParam);
The filter method does not change the array it acts upon. That is it does not mutate words array. The value of words array does not change. Rather it returns a filtered array. shortWords is that filtered array.
For each array element, if the condition returned by the filterFunctionAsParam is true, the element is returned by the filter function.
This can also be achieved with Array.map, Array.reduce methods.
My current assumption is that shortWords is a function that is having another function passed in as a parameter.
No, filter is a function which has another function passed to it as a parameter.
It operates on an array, and calls the passed-in function on each element in the array - if it returns true then that array item is included in the result of calling filter.
Can anybody explain the flow of the code? I need to know how the function 'isEven' gets the 'x' value
$(document).ready(function(){
var array = [1,2,3,4,5];
function isEven(x){ //checks if a value is even
console.log(x)
return x % 2 == 0;
}
var newArray = array.filter(isEven); //uses a callback to check if an element is even
console.log(newArray);
});
As stated in the comment in your code, you are passing a callback, so here the current item processed in .filter() will be automatically passed to this callback function, or in other words isEven function will be called with the current item from .find() call.
As you can see in the MDN Reference for .find():
callback
Function to execute on each value in the array, taking three
arguments:
element The current element being processed in the array.
So writing:
array.filter(isEven);
Is equivalent to writing:
array.filter(function(item){
isEven(item);
});
The solution is in this line
var newArray = array.filter(isEven); //uses a callback to check if an element is even
Here you are calling the method "filter" on the array. Filter takes a method that returns true or false, and calls it on each of the array element, passing the element itself. That line could be implemented like this
let newArray;
for(let x: array){
if(isEven(x)){
newArray.push(x);
}
}
The filter() function on an array takes a function as it's input. In this case that input function is the isEven function. The filter function then iterates over the array and runs the isEven function over each of the elements. It then filters out any elements in the array for which the function returned false.
Note that in the parentheses of the filter function you do not specify any arguments to the isEven function. That is because filter does this for you.
Your code is equivalent to:
var newArray = [1, 2, 3, 4, 5].filter(x => x % 2 == 0);
The x value is taken in your first array. See the doc.
filter is a function defined in the Array API, it receives as a parameter a "this" which in your case is the variable "array" and a callback that would be "isEven", inside that "this" is the values of your array, it just need to go through it and call each one to your function.
Read this
array.filter will automatically take this as its argument if not passed, when it is getting looped. Check here for more details.
So, in case of your array this values corresponds to the elements 1,2,3,4,5
If a thisArg parameter is provided to filter, it will be used as the
callback's this value. Otherwise, the value undefined will be used as
its this value. The this value ultimately observable by callback is
determined according to the usual rules for determining the this seen
by a function.
I have an algorithm :
let someArray = [1, 2, 3, 4, 5]
let mapped = someArray.map(number => {
let index = someArray.indexOf(5)
if (index !== -1) {
someArray.splice(index, 1)
}
console.log(typeof number)
return number
})
console.log(mapped)
console.log(mapped.length)
console.log(Object.keys(mapped).length)
So what I expected to have was mapped=[1,2,3,4] and mapped.length=4
But instead I have mapped=[1,2,3,4,empty] and mapped.length=5.
So what I thought is : in the beginning, map is going for 5 iterations so it does it no matter what. That's why I added console.log(typeof number).
But it's executed only 4 times.
I know to have my expected result, filter is way better. I'm just wondering, what is happening here ?
See MDN documentation:
map calls a provided callback function once for each element in an array, in order, and constructs a new array from the results. callback is invoked only for indexes of the array which have assigned values, including undefined. It is not called for missing elements of the array (that is, indexes that have never been set, which have been deleted or which have never been assigned a value).
If existing elements of the array are changed, their value as passed to callback will be the value at the time map visits them. Elements that are deleted after the call to map begins and before being visited are not visited.
You're mutating the array as you're iterating over it, which means that once index [4] is reached, that element (whose value used to be 5) doesn't exist anymore, which means the function does not get called on that iteration, resulting in <empty>. The resulting array is created with 5 elements, but the callback is never called on the last element.
Use filter instead.
The following function returns the index of an object:
selectedAppIndex: function () {
console.log(this.activeApps)
console.log(this.selectedApp)
return this.activeApps.findIndex(this.selectedApp)
}
console.log(this.activeApps) logs the array:
console.log(this.selectedApp) logs the object:
As you can see the object in the array and the object in this.selectedApp is the same. So the function should output 0.
However I get this error:
Uncaught TypeError: #<Object> is not a function
(I'm using Chrome 49. And findIndex() is supported from Chrome 45.)
Your problem is due the fact that findIndex expect a function as a parameter not an object.
Inside of this function you define the condition to find the first the index of the first match.
For example if you are looking for the index of the number 12:
function search12(el){
return el === 12;
}
[4, 6, 8, 12].findIndex(search12);
The above example will return the number 3, since 12 is located on the index 3.
Inside of the function that is passed to findIndex you have 3 parameters that can be used for test.
element, is the current element being processed present in the original array.
index, The index of the current element being processed, or the result if the test evaluates to true.
array The original array findIndex was called upon.
More info.
As you can see on the function above you have to return the case where you have a match, because the function passed as a parameter is being executed every time per each element until is evaluated to true if some element evaluates to true will return that index if non element inside of the array evaluates to true will return -1
If you want to get the index of a value in an array, use indexOf:
return this.activeApps.indexOf(this.selectedApp)
If there's anyone who can help me understand this one, I will be impressed. It's #28 from John Resig's advanced JavaScript.
Here's a function for looping, and, if you look at the tutorial, it seems to run 3 times producing the 6 Pass below.
Can you please explain in plain language in as much detail as possible what is happening in this program, explaining along the way:
fn.call(array, array[i], i) Why are there these 3 parameters to the function and how do they all work. Does the function first deal with array, then array[i], and then i? What's happening when all that is going on?
Also, in the function, I understand that i++ goes up every time that it goes through the array.length, but what triggers num++ to increase it's value, and in what way is value == num++
In function(value, i), what is value? Is value alternately 0,1,2 of the loop array? If so, how do those loop array numbers get passed as a parameter in function(value, i)
this instanceof Array what is this trying to show? How?.
Code:
function loop(array, fn){
for ( var i = 0; i < array.length; i++ )
fn.call( array, array[i], i );
}
var num = 0;
loop([0, 1, 2], function(value, i){
assert(value == num++, "Make sure the contents are as we expect it.");
assert(this instanceof Array, "The context should be the full array.");
});
PASS Make sure the contents are as we expect it.
PASS The context should be the full array.
PASS Make sure the contents are as we expect it.
PASS The context should be the full array.
PASS Make sure the contents are as we expect it.
PASS The context should be the full array.
The function is an anonymous function, that is, a function without a name. The full second argument to loop is
function(value, i) {
assert(value == num++, "Make sure the contents are as we expect it.");
assert(this instanceOf Array, "The context should be the full array.");
}
which is a complete anonymous function which takes three arguments: this (the object for which it is a method), the current value, and the loop counter.
loop iterates over the array, and uses fn.call to invoke the anonymous function, passing it three arguments; here, the array object must be explicit, because call can't know what context the function reference it's being invoked on should be invoked in (that is, what to make this in the call).
The anonymous function, as invoked by loop, receives the array as this. The second ASSERT verifies this. It also expects that the array's value is [0, 1, 2] and verifies this by incrementing num on each call and comparing that to the passed array element.
So, following the execution chain:
num is declared and initialized to 0.
loop([0, 1, 2], function ...) is invoked.
loop invokes fn, the anonymous function, with the array (as this), its first element, and i which indicates the element offset. (i is never actually used.)
The anonymous function ASSERTs that it was passed the expected first element, 0, by comparing against num and incrementing num afterward.
The anonymous function ASSERTs that its this is an Array.
loop invokes fn as in #3, but with the second array element.
The anonymous function again performs its ASSERTs, this time comparing the passed second array element, which is expected to be 1, against num (which, because of the post-increment in step 4, is 1).
loop invokes fn as before with the third array element.
The anonymous function does its ASSERTs again, this time comparing the expected array element 2 against num whose value is now 2.
fn is a function pointer to the anonymous function that was created when invoking loop.
a) There are three parameters because the first one is a reference to the object you are going to be acting on, i.e. the array, the 2nd parameter is just current value in the iteration of the array, and the third value is location of that element in that array.
b) when you call num++, it increments the value of num. The post increment returns the value (aka assigns to value) and then increments num.
c) value is the 2nd parameter passed in by fn.call a couple lines up.
d) this refers to the array that you passed into the first parmater in your fn.call() invocation.
I think an easier way to understand what's going on is to remove the usage of call and instead invoke the method directly - the old fashioned way.
function loop(array, fn) {
for(var i = 0; i < array.length; i++)
fn(array[i], i);
}
var num = 0;
loop([0, 1, 2], function(value, i) {
assert(value == num, "Make sure the contents are as we expect it.");
assert(this instanceof Array, "The context should be the full array.");
num++;
});
If you run this code on the source url, you would see the this instanceof Array test fails each time, since this is not pointing to an instance of Array anymore.
To make this point to an instance of Array, we need to invoke the method using call or apply.
fn.call(array, array[i], i);
The first parameter is what this will point to. All other parameters here are passed as arguments to the function being called. Note that we can cheat here to pass the test. Instead of passing the array object that we are looping over, you can pass any Array object to make the second test pass.
fn.call([], array[i], i);
fn.call([1,2,3,4,5], array[i], i);
I don't actually know javascript but I believe I understand whats going on...
The first four lines are defining a function called loop. Loop takes in two variables, an array and a function. The only reason why I believe the second parameter is function is because the coder called call on the variable which probably calls the function. The function loops through the elements of the array and passes them to the function somehow through the call method. You should probably look this part up.
After the definition, num is defined to start at zero.
Then comes the fun part. The function loop is called with the parameters [0, 1, 2] and an anonymous function that was created on the spot. function(value, i) and everything after it is the definition of this anonymous function. It has no name but it just defined for this function call. The function checks to make sure that value equals num and increments num after it and then checks to makes sure the variable is an array.