How to display only the latest data received? - javascript

Hey I am trying to show only the latest message of the day,
Thing is I am not sure how to do that as my code only picks up the one I first wrote..
it's not even the first object in the array.. but it still takes it.
*Note that this code runs every few seconds in intervals to check for new data received.
Below is the response I am using my logic on and the code with the logic
isMOTD = false;
var i = 0;
var MOTD = "";
while (messages[i].text && isMOTD == false) {
i++;
isMOTD = messages[i].text.includes("MOTD");
if (isMOTD)
MOTD = messages[i].text;
}
if (isMOTD) {
console.log(MOTD+' ' +'THIS IS MSG OF THE DAY')
$('.content', el).html(MOTD);
}
}
};

I would do something like this:
var MOTD = messages.filter(message => message.text.includes("MOTD"))
.reduce((a, b) => a.ts > b.ts ? a : b, {ts: -1, text: ''})
.text;
$('.content', el).html(MOTD);
The .filter() creates a new array which only includes messages with MOTD in them.
the .reduce() is going through that filtered array and keeping only the message who's timestamp is highest. I also have it default to an empty string if there are no strings that contain MOTD
And then .text, to deal with just the string, not the timestamps.
EDIT: i've been requested to add some more explanation.
First: arrow functions. EcmaScript 2015 (one of the newer versions of javascript) gave a new way to write functions. When you see an =>, think "function". Rather than doing this:
function (a, b) {
return a + b;
}
you can do this:
(a, b) => {
return a + b;
}
Or if there's just one statement as in this case, you can leave off the curly brackets, the semicolon, and the return:
(a, b) => a + b
Second: .filter. All arrays have a function on them called .filter. As the name suggests, the purpose is to filter the array. You pass in a function that describes how you want it to be filtered, and then it creates a new array with just the matching elements.
So consider the following:
var myArray = [1, 2, 3, 15, 18, 200];
var evenNumbers = myArray.filter(function (num) {
return num % 2 == 0
});
It will loop through the array, and for each element of the array, it calls the function i specified. If the function returns true, then that element is included. If the function returns false, then the element is not included. So for this sample code, evenNumbers will equal [2, 18, 200]
For your case, the filter that i'm doing is:
messages.filter(function (message) {
return message.text.includes("MOTD");
});
So the array that's returned by this will contain all messages who's text includes "MOTD". messages that lack "MOTD" are excluded.
Third: .reduce. All arrays have this function as well. Reduce is quite a versatile function, but the general purpose is to take your array, and in some way boil it down (or "reduce" it) to a single value. You pass in some function that you want to be called for every element of the array. When your function returns a value, that value gets carried forward and used the next time the function is run. Here's an example where i want to sum up all the numbers in an array:
var myArray = [1, 2, 3, 4];
var total = myArray.reduce(function (sumSoFar, current) {
var newSum = sumSoFar + current;
return newSum;
}, 0); //<--- this 0 is the initial value
So here's how it works: It's going to start with the initial value of 0, and then it calls the function. SumSoFar will be 0 at this point (because of the intial value), and current is 1 (because we're starting with the first element of the array, which has a value of 1). The function adds them together, and then returns a new sum of 1. Then the function gets called again, but now sumSoFar is 1 (because that's what was returned the last time), and current is 2 (because we're looking at the second element). It adds 1 + 2, and returns a new sum of 3. And so it continues, adding 3 + 3 to get 6, then adding 6 + 4 to get 10. We're done going the the array, so the final value is 10.
In your case, i want to step through the array and find only the message with the most recent timestamp. I start with an initial value of {ts: -1, text: ''}, because in case there are no messages with "MOTD" in them, i want to have the empty string be the result.
.reduce(function (mostRecentMessageSoFar, currentMessage) {
if (mostRecentMessageSoFar.ts > currentMessage.ts) {
return mostRecentMessageSoFar;
} else {
return currentMessage;
}
}, {ts: -1, text: ''});
So this will walk its way through the array (and remember, we're walking through the filtered array, so they all have "MOTD" in them), it is looking for the most recent message. Any time currentMessage is more recent than the best we've found so far, it switches to that one being the best so far. And in the end, we get the most recent message from the entire array.
That final message is an object that looks something like this:
{
type: 'message',
user: 'U0GL3BR52',
text: 'SOLVE MORE CASES #MOTD',
ts: 1505236695.000533
}
Only the text needs to be put into the dom, so i access that with .text
So, in long form, my solution is this:
var MOTDMessages = messages.filter(function (message) {
return message.text.includes("MOTD");
});
var MostRecentMOTDMessage = MOTDMessages.reduce(
function (mostRecentMessageSoFar, currentMessage) {
if (mostRecentMessageSoFar.ts > currentMessage.ts) {
return mostRecentMessageSoFar;
} else {
return currentMessage;
}
}, {ts: -1, text: ''});
var MOTDText = MostRecentMOTDMessage.text;
$('.content', el).html(MOTDText);

Just sort your message after time descending:
messages.sort((a,b) => b.ts - a.ts );
Then just take the first one:
messages[0]

Related

How are the variables populated in this Javacript snippet plus a couple of other questions

I'm a backend developer but would like to figure out this snippet of javacript. I've put some comments on the pieces I get, but have boldfaced questions for the parts I don't.
function transformData (output) {
// QUESTION:
// what the difference between "{}" and "[]" below?
const filteredData = {};
const Statistics = [];
// this is an array of the codes
const NORCA_CODE = [
'QFV1D_START_CHARACTER_CORRECTED',
'QFV1D_STOP_CHARACTER_CORRECTED',
'QFV1D_BUFFER_DECODING_FAILED'
]
// this is to create Series 0, which is the X axis. It just has the systems, e.g, 01, 02,
// etc.
/* Series 0 */
// Here it's creating data0.
// It's going to use an array function to create a set
// Any system name it finds, it's going to put it in data0, then it will sort it
const data0 = Array.from(new Set(output.map(({ systemName }) => systemName))).sort();
// It's going to create a series0 json object which will probably
// look like "["systemName": "01","systemName": "02", ...]
var series0 = {
name: 'systemName',
data: data0.map(d => `System ${d}`)
}
// The system / name series will be pushed to a Statics object as series 0 for the graph
Statistics.push(series0);
// This looks like it's going to iterate over data0, which contains systems,
// and for each system, iterate over the output
// (which is actually input from an API)
// And if the system name matches is going to add to "acc" (accumulated total
// for the system if the input (cur.system name) matches the system name
// from from data0 (systems)
// QUESTIONS:
// question 1 - where is acc coming from? Is it a dynamic variable?
// question 2 - why does it return acc if there's no match? To give the current system
// the same total it had previously?
// question 3 - why does it return a zero at the end? How does it fit into the picture?
// question 4 - Is this getting total objects for the system?
const norcaBase = data0.map(systemName => output.reduce((acc, cur) => {
if (cur.systemName === systemName) {
return acc + cur.sum
}
return acc
}, 0))
// Create an array of norca data
const norcaData = {}
// iterate through the NORCA codes
NORCA_CODE.forEach((code) => {
// for the current code iterate through the system names
norcaData[code] = data0.map(systemName => output.reduce((acc, cur) => {
// if the system name and code match, accumulate
if (cur.systemName === systemName && cur.norcaCode === code) {
return acc + cur.sum
}
return acc
}, 0))
})
// iterate through the NORCA Codes
// question: is "i" an increment?
NORCA_CODE.forEach((code, i) => {
// Push the code and percentage of total into Statistics
// QUESTION
// question: where does "d" from? looks the the total for that Norca Code
Statistics.push({
name: code,
data: norcaData[code].map((d, i) => norcaBase[i] ? d / norcaBase[i] : 0)
})
})
// Put the chart-data entry in filteredData
filteredData['chartData'] = {};
// Put the Statistics into chart data
filteredData['chartData']['Statistics'] = Statistics;
// return filtered daa
return filteredData;
}
// what the difference between "{}" and "[]" below?
{} creates an object. Javascript objects are similar to maps or dictionaries in other languages and store unordered key/value pairs. [] creates an array for storing ordered data.
Taking your questions out of order:
// question 4 - Is this getting total objects for the system?
Generally speaking, the purpose of reduce is to step through an array, and "combine" elements of the array. You provide a function which describes how you want to combine them. Reduce will then step through the array, calling your function for every element of the array. When it calls your function it passes in the value so far (often called the "accumulator"), and the element of the array currently being looked at, and then your function is responsible for returning the new value of the accumulator.
In your specific case, this code is adding up the .sum properties of every element in the array who's systemName matches.
// question 3 - why does it return a zero at the end?
That 0 is the initial value of the accumulator. It's being passed into reduce, not returned.
// question 1 - where is acc coming from?
It's passed in to you by the code for reduce. acc will be 0 the first time your function is called (see question 3), and on subsequent calls it will be whatever value you returned the last time.
// question 2 - why does it return acc if there's no match?
Because this code wants the accumulator to not change for that case. Ie, it's not adding anything to it.
// question: is code an increment?
Not sure what you mean by an increment. .forEach will loop over each element of the array and call the function you provided for each of them. The first argument that will be passed in (here named code) is the element of the array.
// question: where does "d" from?
.map will call the function you provide once for each element of the array. The first argument is the element of the array. The difference between .map and .forEach is that with .map you are creating a new array, the values of which are whatever you return via your function (.forEach pays no attention to what you return).

ReactJS : Nothing return even if the Condition is true [duplicate]

I know that there were a lot of topics like this. And I know the basics: .forEach() operates on original array and .map() on the new one.
In my case:
function practice (i){
return i+1;
};
var a = [ -1, 0, 1, 2, 3, 4, 5 ];
var b = [ 0 ];
var c = [ 0 ];
console.log(a);
b = a.forEach(practice);
console.log("=====");
console.log(a);
console.log(b);
c = a.map(practice);
console.log("=====");
console.log(a);
console.log(c);
And this is output:
[ -1, 0, 1, 2, 3, 4, 5 ]
=====
[ -1, 0, 1, 2, 3, 4, 5 ]
undefined
=====
[ -1, 0, 1, 2, 3, 4, 5 ]
[ 0, 1, 2, 3, 4, 5, 6 ]
I can't understand why using practice changes value of b to undefined.
I'm sorry if this is silly question, but I'm quite new in this language and answers I found so far didn't satisfy me.
They are not one and the same. Let me explain the difference.
forEach: This iterates over a list and applies some operation with side effects to each list member (example: saving every list item to the database) and does not return anything.
map: This iterates over a list, transforms each member of that list, and returns another list of the same size with the transformed members (example: transforming list of strings to uppercase). It does not mutate the array on which it is called (although the callback function may do so).
References
Array.prototype.forEach() - JavaScript | MDN
Array.prototype.map() - JavaScript | MDN
Array.forEach “executes a provided function once per array element.”
Array.map “creates a new array with the results of calling a provided function on every element in this array.”
So, forEach doesn’t actually return anything. It just calls the function for each array element and then it’s done. So whatever you return within that called function is simply discarded.
On the other hand, map will similarly call the function for each array element but instead of discarding its return value, it will capture it and build a new array of those return values.
This also means that you could use map wherever you are using forEach but you still shouldn’t do that so you don’t collect the return values without any purpose. It’s just more efficient to not collect them if you don’t need them.
forEach()
map()
Functionality
Performs given operation on each element of the array
Performs given "transformation" on a "copy" of each element
Return value
Returns undefined
Returns new array with transformed elements, leaving back original array unchanged.
Preferrable usage scenario and example
Performing non-tranformation like processing on each element. For example, saving all elements in the database.
Obtaining array containing output of some processing done on each element of the array. For example, obtaining array of lengths of each string in the array
forEach() example
chars = ['Hello' , 'world!!!'] ;
var retVal = chars.forEach(function(word){
console.log("Saving to db: " + word)
})
console.log(retVal) //undefined
map() example
chars = ['Hello' , 'world!!!'] ;
var lengths = chars.map(function(word){
return word.length
})
console.log(lengths) //[5,8]
The main difference that you need to know is .map() returns a new array while .forEach() doesn't. That is why you see that difference in the output. .forEach() just operates on every value in the array.
Read up:
Array.prototype.forEach() - JavaScript | MDN
Array.prototype.map() - JavaScript | MDN
You might also want to check out:
- Array.prototype.every() - JavaScript | MDN
Performance Analysis
For loops performs faster than map or foreach as number of elements in a array increases.
let array = [];
for (var i = 0; i < 20000000; i++) {
array.push(i)
}
console.time('map');
array.map(num => {
return num * 4;
});
console.timeEnd('map');
console.time('forEach');
array.forEach((num, index) => {
return array[index] = num * 4;
});
console.timeEnd('forEach');
console.time('for');
for (i = 0; i < array.length; i++) {
array[i] = array[i] * 2;
}
console.timeEnd('for');
forEach: If you want to perform an action on the elements of an Array and it is same as you use for loop. The result of this method does not give us an output buy just loop through the elements.
map: If you want to perform an action on the elements of an array and also you want to store the output of your action into an Array. This is similar to for loop within a function that returns the result after each iteration.
Hope this helps.
map returns a new array.
forEach has no return value.
That's the heart of the difference. Most of the other answers here say effectively that, but in a much more convoluted way.
forEach() :
return value : undefined
originalArray : not modified after the method call
newArray is not created after the end of method call.
map() :
return value : new Array populated with the results of calling a provided function on every element in the calling array
originalArray : not modified after the method call
newArray is created after the end of method call.
Conclusion:
Since map builds a new array, using it when you aren't using the returned array is an anti-pattern; use forEach or for-of instead.
The difference lies in what they return. After execution:
arr.map()
returns an array of elements resulting from the processed function; while:
arr.forEach()
returns undefined.
one of the shuttle difference not mentioned here is that forEach() can loop over static (not live) NodeList while map() cannot
//works perfectly
document.querySelectorAll('.score').forEach(element=>console.log(element));
//Uncaught TypeError: document.querySelectorAll(...).map is not a function
document.querySelectorAll('.score').map(element=>console.log(element));
Diffrence between Foreach & map :
Map() : If you use map then map can return new array by iterating main array.
Foreach() : If you use Foreach then it can not return anything for each can iterating main array.
useFul link : use this link for understanding diffrence
https://codeburst.io/javascript-map-vs-foreach-f38111822c0f
Difference between forEach() & map()
forEach() just loop through the elements. It's throws away return values and always returns undefined.The result of this method does not give us an output .
map() loop through the elements allocates memory and stores return values by iterating main array
Example:
var numbers = [2,3,5,7];
var forEachNum = numbers.forEach(function(number){
return number
})
console.log(forEachNum)
//output undefined
var mapNum = numbers.map(function(number){
return number
})
console.log(mapNum)
//output [2,3,5,7]
map() is faster than forEach()
One thing to point out is that both methods skips uninitialized values, but map keeps them in the returned array.
var arr = [1, , 3];
arr.forEach(function(element) {
console.log(element);
});
//Expected output: 1 3
console.log(arr.map(element => element));
//Expected output: [1, undefined, 3];
Performance Analysis (again - not very scientific)
In my experience sometime .map() can be faster than .foreach()
let rows = [];
for (let i = 0; i < 10000000; i++) {
// console.log("here", i)
rows.push({ id: i, title: 'ciao' });
}
const now1 = Date.now();
rows.forEach(row => {
if (!row.event_title) {
row.event_title = `no title ${row.event_type}`;
}
});
const now2 = Date.now();
rows = rows.map(row => {
if (!row.event_title) {
row.event_title = `no title ${row.event_type}`;
}
return row;
});
const now3 = Date.now();
const time1 = now2 - now1;
const time2 = now3 - now2;
console.log('forEach time', time1);
console.log('.map time', time2);
On my macbook pro (late 2013)
forEach time 1909
.map time 444
.map and .forEach will do just about then same thing, until you start operating on arrays with millions of elements. .map will create another collection with the same size (and possibly type, depending on the array species) which could use up a LOT of memory. .forEach will not do this.
const arr = [...Array(100000000).keys()];
console.time("for");
for (let i = 0; i < arr.length; i++) {}
console.timeEnd("for");
console.time("while");
let j = 0;
while (j < arr.length) {
j++;
}
console.timeEnd("while");
console.time("dowhile");
let k = 0;
do {
k++;
} while (k < arr.length);
console.timeEnd("dowhile");
console.time("forEach");
arr.forEach((element) => {});
console.timeEnd("forEach");
VM35:6 for: 45.998046875 ms
VM35:13 while: 154.581787109375 ms
VM35:20 dowhile: 141.97216796875 ms
VM35:24 forEach: 776.469970703125 ms
Map implicitly returns while forEach does not.
This is why when you're coding a JSX application, you almost always use map instead of forEach to display content in React.

Javascript - find latest object depending of value

I've tried to find a way to search the latest value of object, and what I found almost all using reverse() or by using i-- in for loop, but I want to avoid it somehow
I can archive it using two var like this:
var a = [{a:true},{a:true},{a:false}]
var b = a.filter(el=>el.a == true)
console.log(b[b.length-1])
Is there a way to use only one var like this?
var a = [{a:true},{a:true},{a:false}]
a.latestValue(el=>el.a == true)
use find to get only one match.
If you don't like the order, you can reverse it, too.
var a = [{
a:true,
id: 1
},{
a:true,
id: 2,
},{
a:false,
id: 3
}]
const latestValue = a.find(el => el.a === true)
const lastValue = a.reverse().find(el => el.a === true)
console.log(latestValue);
console.log(lastValue);
You're basically looking for something like .find, except a .find that starts at the last item and iterates backwards, rather than starting at the first item and iterating forwards. Although there are built-in functions like lastIndexOf (similar to indexOf, except starts searching from the last element) and reduceRight (same, but for reduce), no such thing exists for .find, so your best option is to write your own function. It's easy enough to write, doesn't mutate the original array (like .reverse() does) and doesn't require creating an intermediate array:
function findRight(arr, callback) {
for (let i = arr.length - 1; i--; i >= 0) {
if (callback(arr[i], i, arr)) return arr[i];
}
}
var a = [{id: 1, a:true},{id: 2, a:true},{id: 3, a:false}];
console.log(
findRight(a, el => el.a === true)
);
I guess it would be possible to (ab)use reduceRight for this, though I wouldn't recommend it:
var a = [{id: 1, a:true},{id: 2, a:true},{id: 3, a:false}];
console.log(
a.reduceRight((a, el) => a || (el.a && el), null)
);
I know already answered but thought it can be achieved in a different way, So here is my solution
You can use JavaScript array map function to get the index of latest value like this
NOTE : I have modified your array to contain more elements
var a = [{a:true},{a:true},{a:false},{a:false},{a:false},{a:true},{a:true},{a:false}];
var latestIndexOfTrue = a.map(function(e) { return e.a; }).lastIndexOf(true)
console.log(latestIndexOfTrue);
/* above will give you the last index of the value you want (here i have tried with
* value true) and it will give you the index as 6 */
if you want whole object then you can get it with bellow code
console.log(a[latestIndexOfTrue]);

Can anybody explain how exactly Filter and IndexOf methods work together in a function?

I have the following function, which pretty much does what it supposed to, but I would like to understand exactly what it does on each steps of its loop.
Could you please take a look to the function below and give me a clear explanation commenting each step or the Filter and IndexOf methods?
Thank you very much in advance.
var arr = [6,2,6,8,9,9,9,4,5];
var unique = function(){
return arr.filter(function(e, i, a) {
return i === a.indexOf(e);
})
}
unique();
indexOf returns the first index of an element in an array:
[1,2,2,3].indexOf(2); // 1
So if you use filter as in your example when it gets to the second occurance of an element the index (i in your example) will not be equal to the value returned by indexOf and be dropped. In my array above the second 2 is at position 2 which obviously doesn't strictly equal the one returned by indexOf.
[1,2,2,3].filter((value, index, array) => array.indexOf(value) === index);
// first iteration: value is 1, index is 0, indexOf is 0 0===0 keep 1
// second: value is 2, index is 1, indexOf is 1, 1===1 keep 2
// third: value is 2, index is 2, indexOf is 1, 1===2 false! toss 2
// etc.
The end effect is that any duplicate elements get dropped from the copy returned by filter. And it is a copy, the original array is not mutated.
EDIT
I should probably mention that recent versions of JavaScript give us a better way:
let arrayWithDupes = [1,2,2,3];
let uniq = Array.from(new Set(arrayWithDupes)); // [1,2,3]
If log the values like:
var arr = [6,2,6,8,9,9,9,4,5];
var unique = function(){
return arr.filter(function(e, i, a) {
console.log('e: ' + e);
console.log('i: ' + i);
console.log('a: ' + a);
return i === a.indexOf(e);
})
}
var unq = unique();
console.log(unq);
you will get:
"e: 6"
"i: 0"
"a: 6,2,6,8,9,9,9,4,5"
and so on...
e = current element from array, i = index of the array, a = array source;
Filer function: "The filter() method creates an array filled with all array elements that pass a test (provided as a function)."
indexOf: "The indexOf() method searches the array for the specified item, and returns its position."

JavaScript: Difference between .forEach() and .map()

I know that there were a lot of topics like this. And I know the basics: .forEach() operates on original array and .map() on the new one.
In my case:
function practice (i){
return i+1;
};
var a = [ -1, 0, 1, 2, 3, 4, 5 ];
var b = [ 0 ];
var c = [ 0 ];
console.log(a);
b = a.forEach(practice);
console.log("=====");
console.log(a);
console.log(b);
c = a.map(practice);
console.log("=====");
console.log(a);
console.log(c);
And this is output:
[ -1, 0, 1, 2, 3, 4, 5 ]
=====
[ -1, 0, 1, 2, 3, 4, 5 ]
undefined
=====
[ -1, 0, 1, 2, 3, 4, 5 ]
[ 0, 1, 2, 3, 4, 5, 6 ]
I can't understand why using practice changes value of b to undefined.
I'm sorry if this is silly question, but I'm quite new in this language and answers I found so far didn't satisfy me.
They are not one and the same. Let me explain the difference.
forEach: This iterates over a list and applies some operation with side effects to each list member (example: saving every list item to the database) and does not return anything.
map: This iterates over a list, transforms each member of that list, and returns another list of the same size with the transformed members (example: transforming list of strings to uppercase). It does not mutate the array on which it is called (although the callback function may do so).
References
Array.prototype.forEach() - JavaScript | MDN
Array.prototype.map() - JavaScript | MDN
Array.forEach “executes a provided function once per array element.”
Array.map “creates a new array with the results of calling a provided function on every element in this array.”
So, forEach doesn’t actually return anything. It just calls the function for each array element and then it’s done. So whatever you return within that called function is simply discarded.
On the other hand, map will similarly call the function for each array element but instead of discarding its return value, it will capture it and build a new array of those return values.
This also means that you could use map wherever you are using forEach but you still shouldn’t do that so you don’t collect the return values without any purpose. It’s just more efficient to not collect them if you don’t need them.
forEach()
map()
Functionality
Performs given operation on each element of the array
Performs given "transformation" on a "copy" of each element
Return value
Returns undefined
Returns new array with transformed elements, leaving back original array unchanged.
Preferrable usage scenario and example
Performing non-tranformation like processing on each element. For example, saving all elements in the database.
Obtaining array containing output of some processing done on each element of the array. For example, obtaining array of lengths of each string in the array
forEach() example
chars = ['Hello' , 'world!!!'] ;
var retVal = chars.forEach(function(word){
console.log("Saving to db: " + word)
})
console.log(retVal) //undefined
map() example
chars = ['Hello' , 'world!!!'] ;
var lengths = chars.map(function(word){
return word.length
})
console.log(lengths) //[5,8]
The main difference that you need to know is .map() returns a new array while .forEach() doesn't. That is why you see that difference in the output. .forEach() just operates on every value in the array.
Read up:
Array.prototype.forEach() - JavaScript | MDN
Array.prototype.map() - JavaScript | MDN
You might also want to check out:
- Array.prototype.every() - JavaScript | MDN
Performance Analysis
For loops performs faster than map or foreach as number of elements in a array increases.
let array = [];
for (var i = 0; i < 20000000; i++) {
array.push(i)
}
console.time('map');
array.map(num => {
return num * 4;
});
console.timeEnd('map');
console.time('forEach');
array.forEach((num, index) => {
return array[index] = num * 4;
});
console.timeEnd('forEach');
console.time('for');
for (i = 0; i < array.length; i++) {
array[i] = array[i] * 2;
}
console.timeEnd('for');
forEach: If you want to perform an action on the elements of an Array and it is same as you use for loop. The result of this method does not give us an output buy just loop through the elements.
map: If you want to perform an action on the elements of an array and also you want to store the output of your action into an Array. This is similar to for loop within a function that returns the result after each iteration.
Hope this helps.
map returns a new array.
forEach has no return value.
That's the heart of the difference. Most of the other answers here say effectively that, but in a much more convoluted way.
forEach() :
return value : undefined
originalArray : not modified after the method call
newArray is not created after the end of method call.
map() :
return value : new Array populated with the results of calling a provided function on every element in the calling array
originalArray : not modified after the method call
newArray is created after the end of method call.
Conclusion:
Since map builds a new array, using it when you aren't using the returned array is an anti-pattern; use forEach or for-of instead.
The difference lies in what they return. After execution:
arr.map()
returns an array of elements resulting from the processed function; while:
arr.forEach()
returns undefined.
one of the shuttle difference not mentioned here is that forEach() can loop over static (not live) NodeList while map() cannot
//works perfectly
document.querySelectorAll('.score').forEach(element=>console.log(element));
//Uncaught TypeError: document.querySelectorAll(...).map is not a function
document.querySelectorAll('.score').map(element=>console.log(element));
Diffrence between Foreach & map :
Map() : If you use map then map can return new array by iterating main array.
Foreach() : If you use Foreach then it can not return anything for each can iterating main array.
useFul link : use this link for understanding diffrence
https://codeburst.io/javascript-map-vs-foreach-f38111822c0f
Difference between forEach() & map()
forEach() just loop through the elements. It's throws away return values and always returns undefined.The result of this method does not give us an output .
map() loop through the elements allocates memory and stores return values by iterating main array
Example:
var numbers = [2,3,5,7];
var forEachNum = numbers.forEach(function(number){
return number
})
console.log(forEachNum)
//output undefined
var mapNum = numbers.map(function(number){
return number
})
console.log(mapNum)
//output [2,3,5,7]
map() is faster than forEach()
One thing to point out is that both methods skips uninitialized values, but map keeps them in the returned array.
var arr = [1, , 3];
arr.forEach(function(element) {
console.log(element);
});
//Expected output: 1 3
console.log(arr.map(element => element));
//Expected output: [1, undefined, 3];
Performance Analysis (again - not very scientific)
In my experience sometime .map() can be faster than .foreach()
let rows = [];
for (let i = 0; i < 10000000; i++) {
// console.log("here", i)
rows.push({ id: i, title: 'ciao' });
}
const now1 = Date.now();
rows.forEach(row => {
if (!row.event_title) {
row.event_title = `no title ${row.event_type}`;
}
});
const now2 = Date.now();
rows = rows.map(row => {
if (!row.event_title) {
row.event_title = `no title ${row.event_type}`;
}
return row;
});
const now3 = Date.now();
const time1 = now2 - now1;
const time2 = now3 - now2;
console.log('forEach time', time1);
console.log('.map time', time2);
On my macbook pro (late 2013)
forEach time 1909
.map time 444
.map and .forEach will do just about then same thing, until you start operating on arrays with millions of elements. .map will create another collection with the same size (and possibly type, depending on the array species) which could use up a LOT of memory. .forEach will not do this.
const arr = [...Array(100000000).keys()];
console.time("for");
for (let i = 0; i < arr.length; i++) {}
console.timeEnd("for");
console.time("while");
let j = 0;
while (j < arr.length) {
j++;
}
console.timeEnd("while");
console.time("dowhile");
let k = 0;
do {
k++;
} while (k < arr.length);
console.timeEnd("dowhile");
console.time("forEach");
arr.forEach((element) => {});
console.timeEnd("forEach");
VM35:6 for: 45.998046875 ms
VM35:13 while: 154.581787109375 ms
VM35:20 dowhile: 141.97216796875 ms
VM35:24 forEach: 776.469970703125 ms
Map implicitly returns while forEach does not.
This is why when you're coding a JSX application, you almost always use map instead of forEach to display content in React.

Categories

Resources