generators in ES6: nested yields? - ecmascript-6

Can anyone explain to me how this code works? (nested yields):
function* anotherGenerator(i) {
yield i + 1;
yield i + 2;
yield i + 3;
}
function* generator(i){
yield i;
yield* anotherGenerator(i);
yield i + 10;
}
var gen = generator(10);
console.log(gen.next().value); // 10
console.log(gen.next().value); // 11
console.log(gen.next().value); // 12
console.log(gen.next().value); // 13
console.log(gen.next().value); // 20
At first console.log() we get a value of 10 ,
after that 11 ..12...13...20... how does this nested yield work?

yield* anotherGenerator(i); is basically a convenient shorthand for
for (var value of anotherGenerator(i)) {
yield value;
}

Related

Generator in ES6

I have the code:
function countA() {
return 1;
}
function* sendStuff() {
let y = yield countA();
console.log("y: ", y);
yield;
}
var gen = sendStuff();
console.log(gen.next().value);
console.log(gen.next().value);
The result is:
> 1
> "y: " undefined
> undefined
Why y is undefined? as I know I should be 1 instead (get from countA result).
Please help me with it. Thank you a lot

let keyword in ES6

Please explain the difference between Both codes. Why Outputs of both are different.
'use strict';
let printNumTwo;
for (let i = 0; i < 3; i++) {
if (i === 2) {
printNumTwo = function() {
return i;
};
}
}
console.log(printNumTwo());
'use strict';
let printNumTwo;
let i;
for (i = 0; i < 3; i++) {
if (i === 2) {
printNumTwo = function() {
return i;
};
}
}
console.log(printNumTwo());
The difference is in the scope where i was declared.
Declares i inside for loop block scope
'use strict';
let printNumTwo;
for (let i = 0; i < 3; i++) { // block scope
// each time we have new variable i
if (i === 2) { // block scope
printNumTwo = function() {
return i; // captures the one that was equal 2
};
}
}
// console.log(i) // throws ReferenceError
console.log(printNumTwo());
Declares i in global scope
'use strict';
let printNumTwo;
let i; // globally scoped
for (i = 0; i < 3; i++) {
if (i === 2) {
printNumTwo = function() {
return i; // captures globally scoped i which will be mutated i++
};
}
}
console.log(i) // prints 3
console.log(printNumTwo());
UPD Some docs Spec
13.7.4.8 Runtime Semantics: ForBodyEvaluation ( test, increment, stmt, perIterationBindings, labelSet ) The abstract operation
ForBodyEvaluation with arguments test, increment, stmt,
perIterationBindings, and labelSet is performed as follows:
Let V be undefined.
Perform ? CreatePerIterationEnvironment(perIterationBindings).
Repeat,
...
e. Perform ? CreatePerIterationEnvironment(perIterationBindings).
f. If increment is not [empty], then ...
Basically new PerIterationEnvironment is created before increment part. So function will capture i === 2.
I will explain only the first example because the second is obvious
'use strict';
let printNumTwo;
for (let i = 0; i < 3; i++) {
if (i === 2) { // block scope
printNumTwo = function() {
return i;
};
}
}
console.log(i)
console.log(printNumTwo());
when you use let inside for loop, it means that the variable i is only defined in the for scope, so in that scope when i is equal to 2 we set the variable printNumTwo, when we do i++ again, i change its value to 3 but it does not change its value inside the for scope, it remains equal to 2, which means if somehow if you wanna access the i value, it is always equal to 2
for (let i = 0; i < 3; i++) {
console.log(i) // prints 0,1,2
}
console.log(i) // undefined
The thing to remember is, even if when i is equal to 2 and we do i++, it does not change its value inside the for scope because i is defined with let

number manipulation in angular

I was trying to convert some number automatically from x=1 to x=00001 so that x takes 5 spaces in total. If x=20.2, I want to format x to be 00020. How can I do that?
I am using html and angularjs. Thanks.
Is this what you want?
function convert(input)
{
var a = Math.floor(input).toString();
return ("00000").substr(0, 5 - a.length) + a;
}
Example:
console.log(convert(20.2)); // 00020
write this filter to achieve the logic
<div>{{number | decimalConvertion:5}}</div>
filter('decimalConvertion', function() {
return function(str, max){
function pad(str, max){
str = str.toString();
return str.length < max ? pad("0" + str, max) : str;
}
return pad(str,8);
};
}
for your reference jsfiddle link

Underscore with count for duplicate values in angular json array

Can anyone please tell me how to put count in duplicate values in angular JSON array:
My actual array is given below:
$scope.datas.resultsOrder =['Data1','Data2','Data3','Data3','Data4','Data4'];
in the above array Data3 and Data4 is repeating twice, so i need it to come as Data3_1, Data3_2, Data4_1, Data4_2 order within that array like as shown below:
$scope.datas.resultsOrder =['Data1','Data2','Data3_1',
'Data3_2','Data4_1','Data4_2'];
Also the values within that array are dynamic values and not static
Can anyone please tell me some solution for this?
I like UnderscoreJS for these kind of problems. In underscoreJS you can do something like this:
function uniq(array) {
var grouped = _.groupBy(array);
return _.reduce(grouped, function(result, x) {
if(x.length > 1) {
_.each(x, function(val, key) {
result.push(val + '_' + (key + 1));
});
} else {
result.push(x[0]);
}
return result;
},[]);
}
uniq(['Data1','Data2','Data3','Data3','Data4','Data4']);
// ["Data1", "Data2", "Data3_1", "Data3_2", "Data4_1", "Data4_2"]
You can do this:
function transform(arr) {
var c = {};
for (var i = 0; i < arr.length; i++) {
var ar = arr[i];
if(! (ar in c) ) {
c[ar] = 0;
}
c[ar]++;
}
var res = []
;
for(var d in c) {
if(c.hasOwnProperty(d)) {
var l = c[d]
;
if(l === 1) {
res.push(d);
continue;
}
for(var i = 0; i < l; i++) {
res.push(d + '_' + (i + 1));
}
}
}
return res;
}
$scope.datas.resultsOrder = transform(passTheArrayHere);
Note: No guarantee for order.

Could someone explain me how this simple function works

From http://www.dartlang.org/language-tour/#functions:
Function makeAdder(num n) {
return (num i) => n + i;
}
main() {
var add2 = makeAdder(2);
print(add2(3)); // 5
}
Could you translate this into english....
what is bothering me is not understanding how it works, and it works..
should it be like this var add2 = makeAdder; and then at print(add2(3)); but then it wont work...
Translating this to JavaScript syntax -- hope this helps:
function makeAdder(n) {
// Returns a new function (closure) that captures the local variable `n`, as
// it was passed to this function. So if `n` is 10, this function essentially
// becomes function(i) { return 10 + i; };.
return function(i) { return n + i; };
}
function main() {
// add2 is now a function that adds 2 to its given argument.
var add2 = makeAdder(2);
print(add2(3)); // 5 is passed to add2 -- the result is 2 + 3 = 5.
}
Each call to makeAdder(num n) creates and returns a new function, defined by lambda expression -- (num i) => n + i. The n is declared with madeAdder, while i with the lambda expression.
With this, makeAdder(2) essentially returns the new function (num i) => 2 + i, which is set as the value of add2.
This is then called as add2(3), which evaluates n + i as 2 + 3, resulting in 5.
This is also an example of currying:
madeAdder(2)(3); // 5