jashkenas / underscore Goto Github PK
View Code? Open in Web Editor NEWJavaScript's utility _ belt
Home Page: https://underscorejs.org
License: MIT License
JavaScript's utility _ belt
Home Page: https://underscorejs.org
License: MIT License
<script type="text/html" id="template">
<% if (data) { data += 12345 } %>
<li><%= data %></li>
</script>
$(document).ready(function(){
var template = _.template(document.getElementById('template').innerHTML);
var $target = $('#target');
$(template({data: 12345})).appendTo($target);
});
works fine, but
<script type="text/html" id="template">
<%
if (data) { data += 12345 } %>
<li><%= data %></li>
</script>
breaks the _.template parsing, returns error:
Error: illegal character
Source File: underscore.min.js
Line: 16, Column: 87
Source Code:
var p=[],print=function(){p.push.apply(p,arguments);};with(obj||{}){p.push('\n\t\t\t');\n\t\t\t\tif (data) { data += 12345 } p.push('\n\t\t\t<li>', data ,'</li>\n\t\t');}return p.join('');
If you look at the description of the native implementation of array.reduce here, you'll notice that the parameters are the inverse of those in underscore: The reduction function precedes the initial value of the memo. Take a gander: http://ejohn.org/blog/javascript-18-progress/
As a consequence, your example code produces an error in node.js (V8 javascript):
var sum = _.reduce([1, 2, 3], 0, function(memo, num){ return memo + num });
TypeError: 0 is not a function
at Array.reduce (native)
at Function. (/Users/masher/code/flikk.it/underscore/underscore.js:98:18)
at Object. (/Users/masher/code/flikk.it/flikk.it.js:34:13)
at Module._compile (node.js:461:25)
at Module._loadScriptSync (node.js:471:10)
at Module.loadSync (node.js:341:12)
at Object.runMain (node.js:524:24)
at node.js:749:10
I have problems getting it to run on node.js
It seems to overwrite itself everytime i use it the first time:
So the second time, the _ object is gone.
How do I make it work on node.js?
Using:
<script type="text/html" id="template">
<%
if (data) { data += 12345; }; %>
<li><%= data %></li>
</script>
</div><!-- /#master -->
<script type="text/javascript">
$(document).ready(function(){
var template = _.template(document.getElementById('template').innerHTML);
var $target = $('#target');
$(template({data: 12345})).appendTo($target);
});
</script>
returns:
<% if (data) { data += 12345; }; %>
template function:
function anonymous(obj) {
var __p = [], print = function () {__p.push.apply(__p, arguments);};
with (obj || {}) {
__p.push("\n\t\t\t<%\n\t\t\tif (data) { data += 12345; }; %>\n\t\t\t
expected:
expected template function:
function anonymous(obj) {
var __p = [], print = function () {__p.push.apply(__p, arguments);};
with (obj || {}) {
__p.push("\n\t\t\t");
if (data) {
data += 12345;
}
__p.push("\n\t\t\t
When prototype.js is loaded, it adds a reduce
function to Array
's prototype. The problem is that it does something completely different than expected.
Either we to check for presence of Prototype (made a patch for that) or some other way to check if obj.reduce
does the right thing.
JS does a pretty good job of comparing arrays with each other. You can easily _.sortBy
a key which is an Array (e.g. ['Artist Name', 'Album Name', 'Song Title']
).
However, arrays don't compare well with Infinity
:
> ['a'] < Infinitiy
false
> ['a'] > Infinitiy
false
> ['a'] == Infinitiy
false
This causes _.min
and _.max
to fail when using Arrays as keys. This is easily fixed, like so:
// Return the maximum item or (item-based computation).
_.max = function(obj, iterator, context) {
if (!iterator && _.isArray(obj)) return Math.max.apply(Math, obj);
var result = {computed : null};
each(obj, function(value, index, list) {
var computed = iterator ? iterator.call(context, value, index, list) : value;
(_.isNull(result.computed) || (computed >= result.computed)) && (result = {value : value, computed : computed});
});
return result.value;
};
I recently started using underscore.js and love it a lot. I see lots of benefits from it, but I have seen one glaring caveat that I want to report.
When an exception occurs in the handler passed to the _.forEach function, the stack trace gets broken, i.e. it does go all the way to the exact cause of exception. This makes debugging the code really difficult.
Fortunately I could figure out why this happens and have a potential solution. In the forEach implementation, you have a try-catch block where you catch the exception thrown by the application handler, you check it against breaker and if it is not breaker then you throw it again. This is the statement at which the stack trace ends, and it never reaches the actual statement (which is in application code). I removed that try-catch and that fixed the stack trace.
I understand you use breaker to implement the breakloop function call.
Is there some way to remove that try-catch and find alternative way to implement breakLoop()?
Thanks.
_.isEqual({x: 1, y: undefined}, {x: 1, z: 2}) returns true, because isEqual only checks that the number of keys in each object is the same, and that each key in a has the same value in b. Since the value of a missing key is undefined, a key in a that has the value undefined will have the same value as a missing key in b.
For array ranges especially, I'd like a way to pass a function that would return a value from a based index. Currently, I'm using slice, but that seems rather pessimized.
Quite often I want the result of 'map' to be an object. That is, I want to return key value pairs and have them be inserted into the result. It seems the only way to do this is using _.each and updating an object procedurally. I'd rather not see details like this in my code, so I wrote a function that does what I want. You can have it. Feel free to change the expected return type of the iterator to pairs (foo, bar) instead if you prefer it.
// Like map, but outputs an object instead of a list
// Expects the iterator to return pairs like {key:foo, value:bar}
_.obj_map = function(obj, iterator, context) {
var results = {};
_.each(obj, function(value, index, list) {
var result = iterator.call(context, value, index, list)
results[result.key] = result.value
});
return results;
};
Two new methods you can add to Underscore.js: isA and grep.
_.isA is for checking inheritance (see : http://gist.github.com/277078 )
ed = new Horse("Mr. Ed");
_.isA(ed, Horse) && _.isA(ed, Animal) && ! _.isA(ed, Snake)
_.filter is great, but much of the time I just want to have it work like a Unix "grep" command and don't want to have to write the inner function. To find all functions in _
starting with the letters 'is', I can do: _.grep(_.functions(_), "^is");
or _.grep(_.functions(_), /^is/i );
Here is the code:
/** find Regular Expression (RegExp) re in the object or Array obj */
_.grep = function(obj,re) {
return _.select(obj, function(s){
var s = (typeof s === "string")?s:new String(s); return s.match(re)
});
};
/**
* return true if o is an instance of c (or a subtype of c).
* Note: isA(null, null) and isA(undefined, undefined) are true,
* but isA(null, undefined) is false.
* isA(o, Object) is almost always true
* -- except when o is primitive type (number, string, or boolean).
* Function will usually return false if c is not a function or constructor.
*/
_.isA = function isA(o,c) {
return o==null ? o===c :
(o.constructor===c || ( typeof c === "function" && o instanceof c));
};
Could use use isString and isFunction instead typeof in above code, but JsLitmus tests showed that they were actually slower that way on Firefox and Chrome on Windows.
Let me know if you would like me to send the JsLitmus test to include in speed.js
Best Regards,
->> Josh W. <<-
I'd love to see a simple data-processing lib like this that's also rhino (or other non-browser engine) compatible:
js> load('underscore.js')
js: "underscore.js", line 17: uncaught JavaScript runtime exception: ReferenceError: "window" is not defined.
at underscore.js:17
at underscore.js:9
at <stdin>:2
For benchmarks see http://www.delicious.com/webEater/benchmark
Currently 3 test cases fail (where cross frame is tested). Is this really important?
If you agree, I will send a patch.
I've extended Underscore by mixing in a debounce function from: http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/
and used it in conjunction with Backbone.sync to limit calls that may be happening several times because of async actions.
It would be nice to have this function in Underscore. Maybe also the throttling stuff:
https://github.com/cowboy/jquery-throttle-debounce/blob/master/jquery.ba-throttle-debounce.js
Calling _.each
, _.indexOf
or _.detect
with a null first value (probably other functions too) currently will cause an error in underscore.js when it tries to do something like obj.forEach.
This error is a little misleading when seen in a debugger, especially when running minimized underscore.js.
Seems like underscore functions should return some sensical value if a null collection is passed in (e.g., each exits silently, indexOf returns -1, etc.).
This is frequently used in jQuery to do code like this:
this.settings = $.extend({}, this.defaults, settings);
Where defaults would be object exposed default values and settings would be the arguments to the constructor with custom settings for this object.
This should already work with
this.settings = _({}).extend(this.defaults).extend(settings).value()
but I think it is quite clumsy in comparison so I would greatly prefer the first solution.
Perhaps a simple memoization routine would do good to sit besides the others in Underscore. Often comes handy to cache the expensiveness.
The version below is a quick implementation. By default uses the first argument as the hash to the cache, but given a function, it'll use that to compute the hash key. A custom hashing function is for cases when costly stuff is called with .toString-less objects.
_.mixin({
memoize: function(fn, hash_fn) {
var cache = {};
hash_fn = hash_fn || _.identity;
return function() {
var k = hash_fn.apply(this, arguments);
return k in cache ? cache[k] : (cache[k] = fn.apply(this, arguments));
};
}
});
Andri
If I have the following:
_($(".something")).map(function() {});
Jquery defines the map function with the index and collection item arguments reversed.
This makes it confusing, because normally underscore has the collection item first.
The source of the issue is the check for the object containing the map function.
if (obj && _.isFunction(obj.map)) return obj.map(iterator, context);
Hi,
Looks like a really nice set of functions and approach.
Was wondering though if you could rename it to "Underscore" since I use "_" as a private variable accessor ( http://brettz9.blogspot.com/2009/02/further-relator-enhancements.html and http://brettz9.blogspot.com/2009/02/true-private-instance-variables-in.html ). There is basically only $ and _ for all these libraries, so I think the chance of conflicts is high.
It shouldn't be too hard for users to add a line:
var _ = Underscore();
...so people could name it as they like "_$" or whatever--without having to mess with your code as one gets updates, etc.
Thanks!
It would be useful to have a function to convert association lists (key-value pairs) to objects. See OCaml extlib's of_enum
, Python's heavily-used dict()
constructor, and Perl's conversion of list expressions to hash tables. This would be especially useful as a companion to _.zip()
, to convert parallel arrays to objects.
A possible implementation:
function assoc(pairs) {
var obj = {};
_.each(pairs, function(pair) {
obj[pair[0]] = pair[1];
});
return obj;
}
_.rest([5, 4, 3, 2, 1]);
instead of
_.rest([5, 4, 3, 2, 1], 1);
Validate Javascript
underscore.js
0 error(s), 9 warning(s)
171: warning: test for equality (==) mistyped as assignment (=)?
if (result = iterator.call(context, value, index, list)) _.breakLoop();
.............................................................^
341: WARNING: block statements containing block statements should use curly braces to resolve ambiguity
for (var i = 0, l = array.length; i < l; i++) if (array[i] === item) return i;
..................................................^
350: WARNING: block statements containing block statements should use curly braces to resolve ambiguity
while (i--) if (array[i] === item) return i;
................^
360: warning: variable start hides argument
start = solo ? 0 : args[0],
........^
361: warning: variable stop hides argument
stop = solo ? args[0] : args[1],
........^
362: warning: variable step hides argument
step = args[2] || 1,
........^
448: WARNING: block statements containing block statements should use curly braces to resolve ambiguity
for (var key in obj) if (hasOwnProperty.call(obj, key)) keys[keys.length] = key;
.........................^
516: WARNING: block statements containing block statements should use curly braces to resolve ambiguity
for (var key in a) if (!(key in b) || !_.isEqual(a[key], b[key])) return false;
.......................^
523: WARNING: block statements containing block statements should use curly braces to resolve ambiguity
for (var key in obj) if (hasOwnProperty.call(obj, key)) return false;
.........................^
This is a feature request: How about a _.methodize() (or some other name) utililty that adds the methods to the native objects?
I know the point of the library is to not extend the native objects, but since all of the methods are defined it would be nice to have a way to make them included.
Please close if you disagree.
Why "without extending any of the built-in JavaScript objects" ?
The following code gives the same error with Prod and Dev versions of 0.54 under MobileSafari but works fine on regular OSX Safari 4.
var a = _([1,2,3,4,5,6,7,8,9,10]).map(function(num) { return num * 3 });
JavaScript Error on Line 67
TypeError: Type error
if I use .each() I get the same error on line 51
Conversely the following works fine:
var a = _.map([1,2,3,4,5,6,7,8,9,10], function(num) { return num * 3 });
Additionally this means I can't use the _(a).chain() syntax which I'm doing all over the place as needed :-(
I have replicated this with Apple's iPhone simulator as well as on my iPhone.
_.isEqual(null,[1]) throws exception.
Underscore collection functions return raw JavaScript objects rather than Underscore wrapper objects. This prevents chaining ร la:
_([1,2,3,4,5]).select(function (n) { return (n %2); }).map(function (n) { return n * 2; }).each(function (n) { console.log(n); })
I was creating a new npm package that depends on underscore.js and was wondering if I should list underscore as a dependency, in which case it will need to be installed into npm, or if I should include it in my package? I see there is a package.json in the root so it seems to me that it might be good to publish it to npm, I didn't see it in the npm list yet.
Thanks,
John
(Wanted to label this with a question but can't seem to get the label control to work.)
The version property is required in package.json to conform to the commonjs package spec. I'm using a package manager for node.js and it wouldn't recognize underscore until I added a version number.
If I pass non "native" object to isNumber in internet explorer (in my case 8) IE throws "Operation not supported" exception
"+obj" causes this error
test case
var xml = new ActiveXObject("Msxml2.DOMDocument.3.0");
xml === +xml;
Wouldn't it be good to have interpolate escape html entities by default via
function escape(html){
String(html)
.replace(/&(?!\w+;)/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
}
In _.template this would require the only change:
.replace(c.html, "',$1,'")
.replace(c.interpolate, "',escape($1),'")
For unescaping interpolate we could introduce a special delimiter, say <%!safeVar%>
Best regards,
--Vladimir
In existing Array.prototype.forEach implementations, a 3rd argument is passed to the passed-in function - the original array. _.each should do this also
What's your take on the differences between Underscore's reduce signature and the official one from ECMA & co?
https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce
http://www.ecmascript.org/docs.php
Seeing that most other Underscore's signatures are fairly identical (few have the added 'context' arg benefit, but still have the same order) to ECMAScript 5's, what was your reasoning to differ with reduce? Is it worth diverging from more well known signatures? Python, I think, also puts the memo as the second arg.
Strings passed into _.isFunction returns true, when it probably shouldn't.
Sometimes, I've had a need to create templates that have no need of interpolation. I know this sounds a little silly ("Isn't that just, uh, a string?") but with a little library of HTML snippets, I value consistency of use over efficiency. So, here's a tiny patch to allow you to call generated template functions with no arguments, for a behaviour equivalent to calling them with an empty object ({}).
I tried doing this:
_.templateSettings = {
start: '{',
end: '}',
interpolate: /{([^}]+?)}/g
};
and then create a template like this:
_.template("I like to '{verb}'!")
I get unexpected string. I even tried this with your mustache templateSettings and same thing.
If you use this : _('blabla').isEmpty() under IE it will return true instead of false.
Works correctly in firefox.
See: https://developer.mozilla.org/en/ECMAScript_DontEnum_attribute#JScript_DontEnum_Bug
This should evaluate to true:
_.extend({}, {a: 1, toString: 'x'}).toString === 'x'
But in IE (I tested version 8) it evaluates to false.
I suggest a patch along these lines: https://prototype.lighthouseapp.com/projects/8886/tickets/23-object-keys-object-values-dontenum-ie-fix
It seems that a single quote inside a string template is fine, but when a second one is introduced, the first one is required to be double escaped. There does not appear to be a way to make more than two inner single quotes work.
Note that all single backslashes below are actually double backslashes but are rendered singly due to the markup engine used.
For example, this works:
_.template(" a'hoy ");
This throws a parse error:
_.template(" a'hoy' ");
This works:
_.template(" a'hoy' ");
This throws a parse error:
_.template(" a'hoy' ' ");
This also throws a parse error:
_.template(" a'hoy' ' ");
As does this:
_.template(" a'hoy' ' ");
Observed in Safari 4.0.4 on Mac OS X Version 10.5.8.
Are there any plans to add support for typed arrays (https://developer.mozilla.org/en/JavaScript_typed_arrays) to underscore.js?
I'm thinking of something like struct module for javascript, that handles packing/unpacking of byte strings to values:
values = _.unpack(myByteString, byteFormat)
Internally, _unpack should use the faster typed arrays for this if available or delegate to the common arrays if not.
Using Underscore in an Appcelerator Titanium iPhone app. Their compiler spits out a slew of linty warnings, below.
Understand completely if you prefer to keep your coding style as is and mark this wontfix, just thought I would report. Thanks for the software.
[WARN] JavaScript compiler reported "Unescaped '^'." at lib/underscore.js:22 [WARN] JavaScript compiler reported "Unescaped '['." at lib/underscore.js:22 [WARN] JavaScript compiler reported "'hasOwnProperty' is a really bad name." at lib/underscore.js:31 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'exports'." at lib/underscore.js:52 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'iterator'." at lib/underscore.js:70 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'iterator'." at lib/underscore.js:73 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'throw'." at lib/underscore.js:77 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'return'." at lib/underscore.js:85 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'return'." at lib/underscore.js:96 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'return'." at lib/underscore.js:106 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'return'." at lib/underscore.js:126 [WARN] JavaScript compiler reported "Expected an assignment or function call and instead saw an expression." at lib/underscore.js:129 [WARN] JavaScript compiler reported "Expected an assignment or function call and instead saw an expression." at lib/underscore.js:138 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'return'." at lib/underscore.js:147 [WARN] JavaScript compiler reported "Expected '{' and instead saw '_'." at lib/underscore.js:150 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'return'." at lib/underscore.js:159 [WARN] JavaScript compiler reported "Expected a conditional expression and instead saw an assignment." at lib/underscore.js:162 [WARN] JavaScript compiler reported "Expected '{' and instead saw '_'." at lib/underscore.js:162 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'return'." at lib/underscore.js:169 [WARN] JavaScript compiler reported "Expected a conditional expression and instead saw an assignment." at lib/underscore.js:172 [WARN] JavaScript compiler reported "Expected '{' and instead saw '_'." at lib/underscore.js:172 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'return'." at lib/underscore.js:192 [WARN] JavaScript compiler reported "Expected an assignment or function call and instead saw an expression." at lib/underscore.js:196 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'return'." at lib/underscore.js:203 [WARN] JavaScript compiler reported "Expected an assignment or function call and instead saw an expression." at lib/underscore.js:207 [WARN] JavaScript compiler reported "Expected an assignment or function call and instead saw an expression." at lib/underscore.js:232 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'return'." at lib/underscore.js:239 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'return'." at lib/underscore.js:240 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'return'." at lib/underscore.js:241 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'return'." at lib/underscore.js:242 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'return'." at lib/underscore.js:281 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'memo'." at lib/underscore.js:297 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'results'." at lib/underscore.js:319 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'return'." at lib/underscore.js:328 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'if'." at lib/underscore.js:329 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'return'." at lib/underscore.js:329 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'return'." at lib/underscore.js:336 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'if'." at lib/underscore.js:338 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'return'." at lib/underscore.js:338 [WARN] JavaScript compiler reported "'start' is already defined." at lib/underscore.js:348 [WARN] JavaScript compiler reported "'stop' is already defined." at lib/underscore.js:348 [WARN] JavaScript compiler reported "'step' is already defined." at lib/underscore.js:348 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'return'." at lib/underscore.js:350 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'return'." at lib/underscore.js:353 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'funcs'." at lib/underscore.js:373 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'return'." at lib/underscore.js:419 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'if'." at lib/underscore.js:421 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'keys'." at lib/underscore.js:421 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'obj'." at lib/underscore.js:438 [WARN] JavaScript compiler reported "The body of a for in should be wrapped in an if statement to filter unwanted properties from the prototype." at lib/underscore.js:438 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'return'." at lib/underscore.js:445 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'return'." at lib/underscore.js:459 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'return'." at lib/underscore.js:462 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'return'." at lib/underscore.js:464 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'return'." at lib/underscore.js:466 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'return'." at lib/underscore.js:468 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'return'." at lib/underscore.js:470 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'return'." at lib/underscore.js:472 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'return'." at lib/underscore.js:475 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'return'." at lib/underscore.js:480 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'return'." at lib/underscore.js:482 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'return'." at lib/underscore.js:486 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'if'." at lib/underscore.js:488 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'return'." at lib/underscore.js:488 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'return'." at lib/underscore.js:494 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'if'." at lib/underscore.js:495 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'return'." at lib/underscore.js:495 [WARN] JavaScript compiler reported "Expected '{' and instead saw 'iterator'." at lib/underscore.js:577 [WARN] JavaScript compiler reported "Bad line breaking before '+'." at lib/underscore.js:626
You have a bunch of aliases of the form:
var slice = Array.prototype.slice
In most, if not all, cases, you then use that as slice.call.
If it's truly done for performance, your aliases should be to
var slicecall = Array.prototype.slice.call
That'll save one more attr lookup in a ton of loops.
It seems odd that _.each creates a pair [key, value] as the items passed to the function parameter. Why not just send the (value, key) instead of ([value,key], index)? I guess that's why _.keys and _.values exist. It seems more consistent in that you can always think of the parameters as value/key instead of having to mentally translate for objects.
If someone really did want the key/value pairs, it would be easy to do this with _.map(function(value,key) { return [key, value] /* or {key:key, value:value} */ }) . Note that incantation wouldn't work today, because _.map uses _.each
Function request:
A _.sortedFind function to go with _.sortedIndex (or perhaps call it _.sortedIndexOf), which would behave similarly to the Array's native indexOf except it would assume it's a sorted array thus using binary search.
_.sortedFind(array, obj, ...)
would return the index position of the first occurrence of obj within array, else -1 if not found.
The code to implement this is almost identical to _.sortedIndex (and therefore could use it) except it would return a -1 if the object is not found.
I wonder why Backbones internal inherits
function, which is really useful isn't included in Underscore.js directly. So it could be used by everyone (not just by Backbone internally). What do you think?
This allows the the webkit and firebug debuggers to display names for functions that are defined with object literals, like this:
function SomeObject(){}
_(SomeObject.prototype).extend({
foo: function(){}
});
Which greatly aids navigating the code in a debugger.
An underscore.js extern file for Google's Closure compiler would make underscore a lot easier to use for me.
You have _.keys(object) and _.values(object), but no _.items(object).
You can likely re-implement this using your own functions, but here's what it should do:
_.items = function(object){
var items = []
for (var key in object){
if (object.hasOwnProperty(key)){
items.push([key, object[key]])
}
}
return items
}
I have a list of search terms, and a list of stop words. I thought this would be the perfect use case for without
.
_.without(search_terms, stop_words)
Unfortunately, you can't just pass a list as the second parameter. It takes a variable number of arguments instead. I can't think of a situation where you would want this, and even if you did you could convert the extra parameters into a list by adding two characters [].
I've changed lines 282-285 of my copy of underscore.js to read as below. You may do this as well.
// Return a version of the array that does not contain the specified value(s).
_.without = function(array, values) {
return _.select(array, function(value){ return !_.include(values, value); });
};
Adding chain()
and value()
can get pretty verbose, particularly if only two or three methods are being called:
_(obj).chain().keys().foldl(...).value()
It would be nice if there was a wrapper that automatically enabled chaining. How about __ and, perhaps, a val()
alias for value()
?:
__(obj).keys().foldl(...).val()
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.