-
-
Save jed/964769 to your computer and use it in GitHub Desktop.
function d( | |
a, // a function to filter the node results (optional) | |
b, // the ancestor element to walk (optional, defaults to document) | |
c // placeholder for the result node list | |
){ | |
b === c && // if b is undefined, | |
(b=document); // use the document | |
c = c || []; // intialize the node list if it doesn't exist | |
if (b) { // if the element exists | |
if ( // and | |
!a || a(b) // matches the filter function if one exists, | |
) c.push(b); // push it to the results. | |
d(a, b.firstChild, c); // repeat for the first child | |
d(a, b.nextSibling, c) // repeat for the next sibling | |
} | |
return c // return the results | |
} |
function d(a,b,c){b===c&&(b=document);c||(c=[]);if(b){if(!a||a(b))c.push(b);d(a,b.firstChild,c);d(a,b.nextSibling,c)}return c} |
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE | |
Version 2, December 2004 | |
Copyright (C) 2011 Jed Schmidt <http://jed.is> | |
Everyone is permitted to copy and distribute verbatim or modified | |
copies of this license document, and changing it is allowed as long | |
as the name is changed. | |
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE | |
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION | |
0. You just DO WHAT THE FUCK YOU WANT TO. |
{ | |
"name": "walk", | |
"keywords": ["walk", "filter", "DOM"] | |
} |
Good catch, thanks!
Same goes for "b = b || document" instead of "1 in arguments || b = document".
@atk this function is actually sensitive to arity, so this suggestion wouldn't work.
Missed that. But I had another idea: why not a typesafe comparison with the uninitialized placeholder variable, e.g.
function d(a,b,c){b===c&&(b=document);c=c||[];
instead of the much longer
function d(a,b,c){c||(c=[]);1 in arguments||(b=document);
Regards, atk
that's a good call, @atk. changed!
Thanks, @jed
Hiya, I just stumbled across this and think i spotted another shortcut (and just created an account to comment ;-) )
basically using ?: to avoid needing brackets in the ifs
b===c&&(b=document); to b=b===c?document:b; saves a character
if(b){if(!a||a(b))...} to b?(!a||a(b0?...:0)...:0 this saves 3 characters, but needs commas to change to +'s and repeatedly flattens & throws away the arrays, which makes it slower :-/
all together :
function d(a,b,c){b=b===c?document:b;c=c||[];b?(!a||a(b)?c.push(b):0)+d(a,b.firstChild,c)+d(a,b.nextSibling,c):0;return c}
and then using the returned arrays instead of referencing c
ie d(a,...,c)+d(a,...,c)
to d(a,...,d(a,...,c))
saves another 2 & stops the arrays getting flattened :-D
function d(a,b,c){b=b===c?document:b;c=c||[];b?(!a||a(b)?c.push(b):0)+d(a,b.firstChild,d(a,b.nextSibling,c)):0;return c}
and then putting (!a||a(b)?c.push(b):0) in an unused parameter
finally 118 characters
function d(a,b,c){b=b===c?document:b;c=c||[];b?d(a,b.firstChild,d(a,b.nextSibling,c,!a||a(b)?c.push(b):0)):0;return c}
Moving the assignment for c
to the first point where it is needed saves 2 bytes:
// 116 bytes
function d(a,b,c){b=b===c?document:b;b?d(a,b.firstChild,d(a,b.nextSibling,c=c||[],!a||a(b)?c.push(b):0)):0;return c}
Switching the ternaries (except for the first one) for Boolean operations saves another 2:
// 114 bytes
function d(a,b,c){(b=b===c?document:b)&&d(a,b.firstChild,d(a,b.nextSibling,c=c||[],!a||a(b)&&c.push(b)));return c}
Moving the return to the front and bringing the ternary back saves 2 more:
// 112 bytes
function d(a,b,c){return(b=b===c?document:b)?d(a,b.firstChild,d(a,b.nextSibling,c=c||[],!a||a(b)&&c.push(b))):c}
And then, if you were allowed to, you could turn it into a slick arrow function saving 14 more bytes:
// 98 bytes
d=(a,b,c)=>(b=b===c?document:b)?d(a,b.firstChild,d(a,b.nextSibling,c=c||[],!a||a(b)&&c.push(b))):c
c = c || [];
could save you 2 byte.