Milena

The woman of many questions
Veteran
Joined
Jan 26, 2014
Messages
1,281
Reaction score
106
First Language
Irish
Primarily Uses
N/A
Just wondering what's the equivalent of the each do function from Ruby to JS?

For example:

$data_actors.each do | actor | #do stuff here endThanks in advance.
 

Milena

The woman of many questions
Veteran
Joined
Jan 26, 2014
Messages
1,281
Reaction score
106
First Language
Irish
Primarily Uses
N/A
Thanks. It is working now, but I wonder why it says that the actor is undefined but when I log it, it says its an Actor object. Figures.
 

DoubleX

Just a nameless weakling
Veteran
Joined
Jan 2, 2014
Messages
1,835
Reaction score
982
First Language
Chinese
Primarily Uses
N/A
Just wondering what's the equivalent of the each do function from Ruby to JS?

For example:

$data_actors.each do | actor | #do stuff here endThanks in advance.
If your Ruby equivalent has return inside the each do:

$data_actors.each do | actor | #do stuff here return if cond #do stuff here endThen Array.prototype.forEach won't work, as return inside forEach is equivalent to continue in a for loop. For instance, the below 2 codes are equivalent of each other:

$dataActors.forEach(function(actor) { // do stuff here if (cond) { return; } // do stuff here});
Code:
for (var index = 0, length = $dataActors.length; index < length; index++) {    // do stuff here    if (cond) { continue; }    // do stuff here}
The below is the equivalent of the above Ruby code:

for (var index = 0, length = $dataActors.length; index < length; index++) { // do stuff here if (cond) { return; } // do stuff here}
Thanks. It is working now, but I wonder why it says that the actor is undefined but when I log it, it says its an Actor object. Figures.
It depends on how your code's actually written :)
 

kentaromiura

Veteran
Veteran
Joined
Nov 1, 2015
Messages
46
Reaction score
26
First Language
English
Primarily Uses
The below is the equivalent of the above Ruby code:



for (var index = 0, length = $dataActors.length; index < length; index++) { // do stuff here if (cond) { return; } // do stuff here}



Just to add that a functional equivalent of this code can be achieved using `Array#some` in this way:

Code:
$dataActors.some(function(actor){
  if(cond) {return true}
})
 
Last edited by a moderator:

DoubleX

Just a nameless weakling
Veteran
Joined
Jan 2, 2014
Messages
1,835
Reaction score
982
First Language
Chinese
Primarily Uses
N/A
Just to add that a functional equivalent of this code can be achieved using `Array#some` in this way:



$dataActors.some(function(actor){
  if(cond) {return true}
})

A bit off topic: Is there any simple and small functional equivalent of the below imperative code?


var data = this.patb_note_data();
for (var index = 0, length = data.length; index < length; index++) {
for (var d = data[index], i = 0, l = d.length; i < l; i++) {
if (d.meta[note]) { return d.meta[note]; }
}
}
return null;


I've tried to write a functional equivalent but it ended up to be much more complicated and convoluted than this imperative one lol
 
Last edited by a moderator:

Iavra

Veteran
Veteran
Joined
Apr 9, 2015
Messages
1,812
Reaction score
889
First Language
German
Primarily Uses
RMMZ
Honestly, i wouldn't bother. Native for-loops are always faster than Array iterators and i prefer performance over "elegant" code.


There is an exception, though: If you want to remove elements from an array while iterating over it, you would need to iterate in reverse or also modify the index, which might not be feasible. Array.forEach creates a shallow copy from the array it iterates over and as such allows modification during the loop.
 
Last edited by a moderator:

kentaromiura

Veteran
Veteran
Joined
Nov 1, 2015
Messages
46
Reaction score
26
First Language
English
Primarily Uses
A bit off topic: Is there any simple and small functional equivalent of the below imperative code?



var data = this.patb_note_data();
for (var index = 0, length = data.length; index < length; index++) {
for (var d = data[index], i = 0, l = d.length; i < l; i++) {
if (d.meta[note]) { return d.meta[note]; }
}
}
return null;


I've tried to write a functional equivalent but it ended up to be much more complicated and convoluted than this imperative one lol




In EcmaScript 2015 there's a couple of new addition to the Array.prototype:


Array#findIndex and Array#find


the latter is what you're looking for in your inner logic, now your logic is more complicated that finding an element if an expression returns true,


as you've nested arrays so you'll need to store the lastIndex visited in the inner loop to know the index you'll need later, I think this is an equivalent:


var lastIndex, found = this.patb_note_data().find(function(data){
return data.find(function(d, index){
lastIndex = index
return d.meta[note]
})
})
return found? found[lastIndex].meta[note]: null


to avoid reassigning lastIndex every step in the loop you can use some short circuit logic and do:


var lastIndex, found = this.patb_note_data().find(function(data){
return data.find(function(d, index){
return d.meta[note] && ~(lastIndex = index)
})
})

return found? found[lastIndex].meta[note]: null


I used the bitwise not (~) operator here, since its value is falsy only if applied to the value -1, since it's impossible to have index -1 as an index of an array, the ~(lastIndex = index) always equates to a truthy value, also thanks to shortcircuiting the left part of the && expression gets evaluated only when the left parts is truthy


It's also possible to use Array#some and directly store the value you're looking for using the same trick as above, this is possibly less readable:
 


var found = null;
this.patb_note_data().some(function(data){
return data.some(function(d, index){
return d.meta[note] && ~(found = d.meta[note])
})
})
return found


I've wrote a little working example here


as Iavra mentioned a for loop may be faster most of the time, I think though it's meaningful to know all the possibility and be aware of all the Array extras methods as they are very easy to work with and you can still optimise later if needed, also is helpful to understand what other people's code does.
 

Latest Threads

Latest Profile Posts

About the Deer, I had to cut some piece of video due the *swearing* Youtube copyrights issues...
A caveman pokes his head in...
I was listening to songs by Chuck E Cheese's voice actor (Jaret Reddick from Bowling for Soup) when the meds I was taking for my stomach virus apparently stopped working. I can't take my next dose until morning, but it's no use anyway. I'm officially sick again. Of course, I'll definitely take the next dose either way, but it's useless now.
New profile picture! This time, it's representative of my current project.
I suddenly feel like making a game for little kids: a pointless sandbox of cute animals, silly collectibles, and random mini games.

Forum statistics

Threads
115,996
Messages
1,094,745
Members
151,298
Latest member
Tapael
Top