I'm looking through some of the JavaScript code of YouTube and I've come across something I've never seen before. Here's the relevant bit of code:
for (var e = window.ytbuffer.queue, a = 0; 5 > a && a < e.length; a++) {
var g = e[a],
h = g.target || g.srcElement;
(0, m.Hf)((0, m.Af)({
a: "buffer_events",
event_index: a,
clientX: g.clientX,
clientY: g.clientY,
localName: h.localName,
className: h.className,
id: h.id,
page_name: (0, m.v)("PAGE_NAME")
}))
}
window.document.removeEventListener ? window.document.removeEventListener("click",
window.ytbuffer.enqueueEvent, !1) : window.document.detachEvent("onclick", window.ytbuffer.enqueueEvent);
(0, m.Wc)("ytbuffer")
What I'm wondering is, what does (0, m.Hf) actually do? I know parenthesis can be used as grouping for mathematical operations, but then I wouldn't expect to see a comma there, and I know that parenthesis can be used to surround function arguments, but there's no function name.
Thanks,
YM
Edit: I used Chrome's inspector on the page and found that m is undefined. This has made me even more confused.
The parens with comma separated expressions inside will return the last expression. So:
(2, 3, 4) + 1 returns 5
So, instead of doing:
alert("Hello World!!")
You could do:
(prompt, alert)("Hello World!!")
Because (prompt, alert) returns alert, right?
That's exactly what's happening in that code
(0, m.Hf)(...) is just calling the m.Hf() method, just with some nesting.
Hope this helps. Cheers
Related
When playing around with JavaScript syntax it struck me that the following code will throw an error in SpiderMonkey and V8 engines:
var a = 1, b = 1;
a++++b;
This to me is strange, since the following works perfectly fine:
var a = 1, b = 1;
a+++b; // = 2; (Add a and b, then increase a)
// now a == 2 and b == 1
a+++-b; // = 1; (add a and -b, then increase a)
// now a == 3 and b == 1
In addition, the following would be nonsensical code:
var a = 1, b = 1;
a++ ++b; // throws an error
My argument is now that if a+++b is equivalent to a++ + b, and not to a+ ++b, and a+++-b is equivalent to a++ + -b, then a++++b can only be interpreted as a++ + +b in order for it to be valid JavaScript code.
Instead, the engines insist that a++++b is interpreted as a++ ++b, by operator precedence.
This to me is in contrast with the logic that the engines implements using the / symbol, as explained here, to distinguish between division and regular expressions. An example
var e = 30, f = 3, g = 2;
e/f/g; // == 5
e
/f/g; // == 5
/f/g; // is equivalent to new RegExp("f","g")
Here the argument is that because /f/g does not make sense as division in the last line, it is interpreted as a regular expression.
Obviously the / symbol gets a special treatment, in order to distinguish between division and regular expressions. But then why do ++ and -- not get a special treatment as well? (That is, outside operator precedence)
A second question is why operator precedence is not called only when the code is has multiple valid interpretations.
In the code a++++b you have two distinct statements: a++ and ++b with nothing to combine them. The + operator in the context of a++ + +b is actually a type converter (meant for turning strings into numbers) and has a different order of precedence which follows the others in the list.
Much apologies for the vague title, but I need to elaborate. Here is the code in question, which I read on http://ariya.ofilabs.com/2013/07/prime-numbers-factorial-and-fibonacci-series-with-javascript-array.html:
function isPrime(i) {
return (i > 1) && Array.apply(0, Array(1 + ~~Math.sqrt(i))).
every(function (x, y) {
console.log(x + ' ' + i % y);
return (y < 2) || (i % y !== 0)
});
}
isPrime(23);
isPrime(19);
isPrime(188);
Just for fun, I added those logs so we can see some output:
undefined NaN
undefined 0
undefined 1
undefined 2
undefined 3
undefined NaN
undefined 0
undefined 1
undefined 1
undefined 3
undefined NaN
undefined 0
undefined 0
This is the first time I have every seen apply and every, so bear with me, but my understanding is that apply basically calls the Array function, where the first argument is the substitution for its this and the second is the output...Never would think that would be useful, but this function seems to work, so...
Here, they seem to be creating an array of length equal to the square root of the number in question. I suppose that makes sense because the square root would be the largest possible factor of the number in question.
OK, so from here, if we were to log that array for, say, the first number, it would look like this:
> var i = 23;
undefined
> Array.apply(0, Array(1 + ~~Math.sqrt(i)));
[ undefined, undefined, undefined, undefined, undefined ]
Great, so it is an array of five undefined. Ok, fine, so from here, the every method is supposed to check whether every element in that array passes the callback function test (or whatever).
The Microsoft documentation specifies three possible arguments for the every method:
value
index
array
Therefore, in this example x is the value, i.e. undefined, and y is the index.
Our output agrees with that conclusion. However, I'm still fuzzy about nested return statements (if the lowest one returns, does its parent also return?), the || operator here (if the first test passes, does the every loop stop?), and just generally how this works.
EDIT
the log should be with an x, not a y. my mistake:
console.log(y + ' ' + i % y); -> console.log(x + ' ' + i % y);
EXPLANATION
So, how did I come across this code, you ask? Well, of course, the simplest way to check for a prime in Java would be like this:
public static boolean isPrime(double num) {
for (double i = 2.0; i < sqrt(num); i++) {
if (num % i == 0.0) {
return true;
}
}
return false;
}
or Python
def isPrime(num):
x = 2
isPrime = True
while x < math.sqrt(num):
if num % x == 0:
isPrime = False
break
x = x + 1
return isPrime
or js
function isPrime(n) {
for (var i = 2.0; i < Math.sqrt(n); i++) {
if (n % i === 0.0) {
return false;
}
}
return true;
}
But say I wanted to check for the largest prime factor of a number like 600851475143 These looping methods would take too long, right? I think this "hack", as we are describing it, may be even less efficient, because it is using arrays instead of integers or floats, but even still, I was just looking for a more efficient way to solve that problem.
The code in that post is basically crap. Teaching people to write code while simultaneously using hacks is garbage. Yes, hacks have their place (optimization), but educators should demonstrate solutions that don't depend on them.
Hack 1
// the 0 isn't even relevant here. it should be null
Array.apply(0, Array(1 + ...))
Hack 2
// This is just Math.floor(x), but trying to be clever
~~x
Hack 3
// this is an outright sin; totally unreadable code
// I bet most people don't know the binding precedence of % over +
y + ' ' + i % y
// this is evaluated as
y + ' ' + (i % y)
// example
2 + ' ' + (5 % 2) //=> "2 1"
I'm still fuzzy about nested return statements (if the lowest one returns, does its parent also return?),
No. A return only return the function the statement exists in
the || operator here (if the first test passes, does the every loop stop?)
No. Array.prototype.every will return false as soon as the callback returns a false. If a false is never returned from the callback, .every will return `true.
function isEven(x) { return x % 2 === 0; }
[2,4,5,6].every(isEven); //=> false, stops at the 5
[2,4,6].every(isEven); //=> true
Here's an example of .every short circuiting
[1,2,3,4,5,6].every(x=> {console.log(x, x<4); return x<4;});
// 1 true
// 2 true
// 3 true
// 4 false
//=> false
See how it stops once the callback returns false? Elements 5 and 6 aren't even evaluated.
... and just generally how this works.
&& kind of works like Array.prototype.every and || kind of works like Array.prototype.some.
&& will return false as soon as the first false is encountered; in other words, it expects every arguments to be true.
|| will return true as soon as the first true is encountered; in other words, it expects only some argument to be true.
Relevant: short circuit evaluation
I am attempting to write a JavaScript function, OneLetterOff, that will take in a String, and an Array of accepted words (WordList).
It should return an array of words from the WordList that only differ from the word given in the String by only one letter, at a single position.
For example:
WordList = ["marc", "bark", "parc", "shark", "mark"];
OneLetterOff("park", WordList); // should return ["bark", "parc", "mark"]
Words that pass the test have to be of the same length, and we can safely assume they are all lower case letters.
How do I use Regular Expressions to solve this algorithm? Essentially, are there ways other than having to use Regular Expressions to solve it?
Thank you so much for your help.
Regular expressions are not the best for it but to give you an idea:
"mark".match(/.ark|p.rk|pa.k|par./) //true
You can, of course, build regular expressions automatically and just "." might not be what you are looking for, depending on the possible characters you need to include.
I suggest you figure out the rest on your own as it looks a lot like homework ;-)
There are many non-regexp ways to solve it. For short words pre-compiled regexp will probably be the most efficient though.
You are looking for words in a list with a Levenshtein distance of 1 from a given word.
As found at Algorithm Implementation/Strings/Levenshtein distance, a JavaScript implementation of the algorithm is as follows:
function levenshteinDistance (s, t) {
if (s.length === 0) return t.length;
if (t.length === 0) return s.length;
return Math.min(
levenshteinDistance(s.substr(1), t) + 1,
levenshteinDistance(t.substr(1), s) + 1,
levenshteinDistance(s.substr(1), t.substr(1)) + (s[0] !== t[0] ? 1 : 0)
);
};
Using that method with Array.prototype.filter (polyfill needed for IE<9) to include only items with a distance of 1, we get a very simple bit of code:
var oneLetterOff = function (word, list) {
return list.filter(function (element) {
return levenshteinDistance(word, element) === 1;
});
};
oneLetterOff('park', ['marc', 'bark', 'parc', 'shark', 'mark']);
// returns ["bark", "parc", "mark"]
One great feature to this approach is that it works for any distance--just change what you're comparing to in the filter.
If you really wanted to use regular expressions (which I would not recommend for this), you would need to:
Iterate the given word to create a set of strings representing regular expression subpatterns where each has one char optional
Combine those string subpatterns into a regular expression using new RegExp()
Iterate the list of words testing them against the expresison
When you get a match, add it to a set of matches
Return the set of matches
It wouldn't take long to write, but given the answer I gave above I think you'll agree it would be a silly approach.
Here is my solution inspired by JAAuide and using all the power of JavaScript functions
function lDist (s, t) {
/* If called with a numeric `this` value
returns true if Levenshtein distance between strings s and t <= this
else
returns the Levenshtein distance between strings s and t */
return this.constructor === Number ? lDist.call (null, s, t) <= this :
s.length && t.length
? Math.min (lDist (s.slice (1), t) + 1,
lDist (t.slice (1), s) + 1,
lDist (s.slice (1), t.slice (1)) + (s.charAt (0) !== t.charAt (0)))
: (s.length || t.length) };
['marc', 'bark', 'parc', 'shark', 'mark'].filter (lDist.bind (1, 'park'));
See the jsFiddle
Code:
var some_var = [/*.......*/];
var compare_var;
for (var i = 0; i < some_var.length - 1; i++){
if (some_var[i] <= compare_var && compare_var < some_var[i + 1]){
return some_var[i];
}
}
One value of some_var is 30 and the next one is 40 and the next one is 50 and compare_var is 42.
It wouldn't return 30 even though it's less-than 42, because 42 isn't less-than 40. Which also means that it would return 40 because it's less-than 42 and 42 is less-than 50.
Edit:
As someone mentioned code translation is not exactly great for SE.so. Just to make it clear: I did try several different things in ruby. I have way more experience in javascript though, so the best way I could think of to phrase my question was to write what I needed out in javascript so that I could see how it translated into ruby. Thanks for the answers
I would use the neato Enumerable#each_cons(n) method:
def foo(arr, x)
arr.each_cons(2) do |a,b|
return a if (a <= x) && (x < b)
end
nil # Not found
end
foo([30,40,50], 42) # => 40
This basically creates a "sliding window" of each pair and then you can just return the first item of the pair when you find the pair that encloses the target value (x).
This is a one-liner:
some_var.select{|v| v < compare_var}.max
Get rid of var key word, change for loop into some_var.each, and you get a working code in Ruby.
PS. Code translation is not proper in StackOverflow
Im reading John Resigs "Learning Advanced JavaScript" http://ejohn.org/apps/learn/#10 and came across this function below that I don`t understand.
The function yell is called with an argument of 4. When this is done, the argument 4 is run through the terniary operator. If it is greater than zero, which it is, then we come to yell(n-1) + a
My questions relate to this.
a) does yell(n-1) + a call the function again (i.e. restart it) with an argument of 3.
b) If you do (n-1) + a, you get a result of 3a. Does JavaScript convert 3a to "aaa". I ask this because in the assert line it says yell(4) == "hiyaaaa"
c) after converting it, does it somehow add it to "hiy"? I don`t understand how.
d) if JavaScript does convert 3a to a string of "aaa"s, and somehow manages to add it to "hiy", I don`t understand why yell(4)=hiyaaaa. Yell(n-1) + a = hiyaaa (3as), not hiyaaaa(4"a"s).
As you can see I am totally confused.
function yell(n){
return n > 0 ? yell(n-1) + "a" : "hiy";
}
assert( yell(4) == "hiyaaaa", "Calling the function by itself comes naturally." );
a) This function is taking advantage of recursion, so yes, the function called again and everything else is pushed on the stack waiting for that return value.
b) No, the function is called with a return value as mentioned above.
c) See Above.
d) It doesn't.
Think of it like this:
function a(val) {
return val + "a";
}
function b(val) {
return a(val) + "a";
}
If you call b("hiya") you'll get hiyaaa. Now instead of calling a different function, call the same one.
a) Yes it calls the function again, so the function is recursive.
b) If one of the operands is a string, + does string concatenation.
c) It returns it.
d) Write the recursion out on paper to better visualise it.
For a), it is known as a recursive function, and yes it is calling self with 3.
For b) you aren't just doing (n-1), you are doing yell(n-1) + "a", and once n =0, yell(0) returns 0.
For c), read the last part of b), i.e. because of the ternary statement, it will return "hiy" once n=0.
For d), see the rest of them.
Try replacing the "a" with the argument supplied to the yell function. Like this:
function yell(n){ return n > 0 ? yell(n-1) + n : "hiy"; }
var x = yell(4); log(x);
assert( yell(4) == "hiy1234", "Calling the function by itself comes naturally." );
So, each value of n is taken and put on a LIFO stack ie 4,3,2,1 and when n becomes 0 "hiy" is on top of the LIFO stack. Then the concatenation is done be popping each value off of the stack such that the string becomes "hiy1234".
Hope this helps.
Bumpfster