diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..9644b34c3 --- /dev/null +++ b/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2009 Jeremy Ashkenas, DocumentCloud + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/README b/README new file mode 100644 index 000000000..037e284fe --- /dev/null +++ b/README @@ -0,0 +1,10 @@ + __ + /\_\ ____ + \/\ \ /',__\ + __ \ \ \/\__, `\ + /\_\_\ \ \/\____/ + _______\/_/\ \_\ \/___/ +/\______\ \ \____/ +\/______/ \/___/ + +See: documentcloud.github.com/underscore \ No newline at end of file diff --git a/index.html b/index.html index 535df71bb..9bec576ee 100644 --- a/index.html +++ b/index.html @@ -12,8 +12,7 @@ } div.container { width: 720px; - margin: 0 auto; - margin-top: 50px; + margin: 50px 0 50px 50px; } p { width: 550px; @@ -32,7 +31,10 @@ background: #f0c095; } h1, h2, h3, h4, h5, h6 { - margin-top: 35px; + margin-top: 40px; + } + b.method_name { + font-size: 18px; } code, pre, tt { font-family: Monaco, Consolas, "Lucida Console", monospace; @@ -47,7 +49,7 @@ font-size: 12px; padding: 2px 0 2px 12px; border-left: 6px solid #aaaa99; - margin: 0px 0 35px; + margin: 0px 0 30px; } @@ -131,7 +133,7 @@

Collection Functions (Arrays or Objects)

- each_.each(list, iterator, [context]) + each_.each(list, iterator, [context])
Iterates over a list of elements, yielding each in turn to an iterator function. The iterator is bound to the context object, if one is @@ -145,7 +147,7 @@ _.each([1, 2, 3], function(num){ alert(num); }); => alerts each number in turn...

- map_.map(list, iterator, [context]) + map_.map(list, iterator, [context])
Produces a new array of values by mapping each value in list through a transformation function (iterator). If the native @@ -156,7 +158,7 @@ _.map([1, 2, 3], function(num){ return num * 3 }); => [3, 6, 9]

- inject_.inject(list, memo, iterator, [context]) + inject_.inject(list, memo, iterator, [context])
Also known as reduce and foldl, inject reduces a list of values into a single value. Memo is the initial state @@ -169,7 +171,7 @@ var sum = _.inject([1, 2, 3], 0, function(memo, num){ return memo + num });

- detect_.detect(list, iterator, [context]) + detect_.detect(list, iterator, [context])
Looks through each value in the list, returning the first one that passes a truth test (iterator). The function returns as @@ -182,7 +184,7 @@ var even = _.detect([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });

- select_.select(list, iterator, [context]) + select_.select(list, iterator, [context])
Looks through each value in the list, returning an array of all the values that pass a truth test (iterator). Delegates to the @@ -194,7 +196,7 @@ var evens = _.select([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });

- reject_.reject(list, iterator, [context]) + reject_.reject(list, iterator, [context])
Returns the values in list without the elements that the truth test (iterator) passes. The opposite of select. @@ -205,7 +207,7 @@ var odds = _.reject([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });

- all_.all(list, [iterator], [context]) + all_.all(list, [iterator], [context])
Returns true if all of the values in the list pass the iterator truth test. If an iterator is not provided, the truthy value of @@ -218,7 +220,7 @@ _.all([true, 1, null, 'yes']);

- any_.any(list, [iterator], [context]) + any_.any(list, [iterator], [context])
Returns true if any of the values in the list pass the iterator truth test. Short-circuits and stops traversing the list @@ -231,7 +233,7 @@ _.any([null, 0, 'yes', false]);

- include_.include(list, value) + include_.include(list, value)
Returns true if the value is present in the list, using == to test equality. Uses indexOf internally, if list @@ -243,7 +245,7 @@ _.include([1, 2, 3], 3);

- invoke_.invoke(list, methodName, [*arguments]) + invoke_.invoke(list, methodName, [*arguments])
Calls the method named by methodName on each value in the list. Any extra arguments passed to invoke will be forwarded on to the @@ -255,7 +257,7 @@ _.invoke([[5, 1, 7], [3, 2, 1]], 'sort');

- pluck_.pluck(list, propertyName) + pluck_.pluck(list, propertyName)
An optimized version of what is perhaps the most common use-case for map: returning a list of property values. @@ -267,7 +269,7 @@ _.pluck(stooges, 'name');

- max_.max(list, [iterator], [context]) + max_.max(list, [iterator], [context])
Returns the maximum value in list. If iterator is passed, it will be used on each value to generate the criterion by which the @@ -280,7 +282,7 @@ _.max(stooges, function(stooge){ return stooge.age; });

- min_.min(list, [iterator], [context]) + min_.min(list, [iterator], [context])
Returns the minimum value in list. If iterator is passed, it will be used on each value to generate the criterion by which the @@ -293,7 +295,7 @@ _.min(numbers);

- sortBy_.sortBy(list, iterator, [context]) + sortBy_.sortBy(list, iterator, [context])
Returns a sorted list, ranked by the results of running each value through iterator. @@ -304,7 +306,7 @@ _.sortBy([1, 2, 3, 4, 5, 6], function(num){ return Math.sin(num); });

- sortedIndex_.sortedIndex(list, value, [iterator]) + sortedIndex_.sortedIndex(list, value, [iterator])
Uses a binary search to determine the index at which the value should be inserted into the list in order to maintain the list's @@ -317,7 +319,7 @@ _.sortedIndex([10, 20, 30, 40, 50], 35);

- toArray_.toArray(list) + toArray_.toArray(list)
Converts the list (anything that can be iterated over), into a real Array. Useful for transmuting the arguments object. @@ -328,7 +330,7 @@ _.sortedIndex([10, 20, 30, 40, 50], 35);

- size_.size(list) + size_.size(list)
Return the number of values in the list.

@@ -340,7 +342,7 @@ _.size({one : 1, two : 2, three : 3});

Array Functions

- first_.first(array) + first_.first(array)
Convenience to return the first element of an array (identical to array[0]).

@@ -350,7 +352,7 @@ _.first([3, 2, 1]);

- last_.last(array) + last_.last(array)
Returns the last element of an array.

@@ -360,7 +362,7 @@ _.last([3, 2, 1]);

- compact_.compact(array) + compact_.compact(array)
Returns a copy of the array with all falsy values removed. In Javascript, false, null, 0, "", @@ -372,7 +374,7 @@ _.compact([0, 1, false, 2, '', 3]);

- flatten_.flatten(array) + flatten_.flatten(array)
Flattens a nested array (the nesting can be to any depth).

@@ -382,7 +384,7 @@ _.flatten([1, [2], [3, [[[4]]]]]);

- without_.without(array, [*values]) + without_.without(array, [*values])
Returns a copy of the array with all instances of the values removed. == is used for the equality test. @@ -393,7 +395,7 @@ _.without([1, 2, 1, 0, 3, 1, 4], 0, 1);

- uniq_.uniq(array, [isSorted]) + uniq_.uniq(array, [isSorted])
Produces a duplicate-free version of the array, using == to test object equality. If you know in advance that the array is sorted, @@ -405,7 +407,7 @@ _.uniq([1, 2, 1, 3, 1, 4]);

- intersect_.intersect(*arrays) + intersect_.intersect(*arrays)
Computes the list of values that are the intersection of all the arrays. Each value in the result is present in each of the arrays. @@ -416,7 +418,7 @@ _.intersect([1, 2, 3], [101, 2, 1, 10], [2, 1]);

- zip_.zip(*arrays) + zip_.zip(*arrays)
Merges together the values of each of the arrays with the values at the corresponding position. Useful when you have separate @@ -428,7 +430,7 @@ _.zip(['moe', 'larry', 'curly'], [30, 40, 50], [true, false, false]);

- indexOf_.indexOf(array, value) + indexOf_.indexOf(array, value)
Returns the index at which value can be found in the array, or -1 if value is not present in the array. Uses the native @@ -442,7 +444,7 @@ _.indexOf([1, 2, 3], 2);

Function (uh, ahem) Functions

- bind_.bind(function, context, [*arguments]) + bind_.bind(function, context, [*arguments])
Bind a function to a context object, meaning that whenever the function is called, the value of this will be the context. @@ -457,7 +459,7 @@ func();

- bindAll_.bindAll(*methodNames, context) + bindAll_.bindAll(*methodNames, context)
Binds a number of methods on the context object, specified by methodNames, to be run in the context of that object whenever they @@ -477,7 +479,7 @@ jQuery('#underscore_button').bind('click', buttonView.onClick);

- delay_.delay(function, wait, [*arguments]) + delay_.delay(function, wait, [*arguments])
Much like setTimeout, invokes function after wait milliseconds. If you pass the optional arguments, they will be @@ -490,7 +492,7 @@ _.delay(log, 1000, 'logged later');

- defer_.defer(function) + defer_.defer(function)
Defers invoking the function until the current call stack has cleared, similar to using setTimeout with a delay of 0. Useful for performing @@ -503,7 +505,7 @@ _.defer(function(){ alert('deferred'); });

- wrap_.wrap(function, wrapper) + wrap_.wrap(function, wrapper)
Wraps the first function inside of the wrapper function, passing it as the first argument. This allows the wrapper to @@ -522,7 +524,7 @@ hello();

Object Functions

- keys_.keys(object) + keys_.keys(object)
Retrieve all the names of the object's properties.

@@ -532,7 +534,7 @@ _.keys({one : 1, two : 2, three : 3});

- values_.values(object) + values_.values(object)
Return all of the values of the object's properties.

@@ -542,7 +544,7 @@ _.values({one : 1, two : 2, three : 3});

- extend_.extend(destination, source) + extend_.extend(destination, source)
Copy all of the properties in the source object over to the destination object. @@ -553,7 +555,7 @@ _.extend({name : 'moe'}, {age : 50});

- clone_.clone(object) + clone_.clone(object)
Create a shallow-copied clone of the object. Any nested objects or arrays will be copied by reference, not duplicated. @@ -564,7 +566,7 @@ _.clone({name : 'moe'});

- isEqual_.isEqual(object, other) + isEqual_.isEqual(object, other)
Performs an optimized deep comparison between the two objects, to determine if they should be considered equal. @@ -579,7 +581,7 @@ _.isEqual(moe, clone);

- isElement_.isElement(object) + isElement_.isElement(object)
Returns true if object is a DOM element.

@@ -589,7 +591,7 @@ _.isElement(jQuery('body')[0]);

- isArray_.isArray(object) + isArray_.isArray(object)
Returns true if object is an Array.

@@ -601,7 +603,7 @@ _.isArray([1,2,3]);

- isFunction_.isFunction(object) + isFunction_.isFunction(object)
Returns true if object is a Function.

@@ -611,7 +613,7 @@ _.isFunction(alert);

- isUndefined_.isUndefined(variable) + isUndefined_.isUndefined(variable)
Returns true if variable is undefined.

@@ -623,7 +625,7 @@ _.isUndefined(window.missingVariable);

Utility Functions

- uniqueId_.uniqueId([prefix]) + uniqueId_.uniqueId([prefix])
Generate a globally-unique id for client-side models or DOM elements that need one. If prefix is passed, the id will be appended to it. @@ -634,15 +636,17 @@ _.uniqueId('contact_');

- template_.template(templateString) + template_.template(templateString, [context])
Compiles Javascript templates into functions that can be evaluated for rendering. Useful for rendering complicated bits of HTML from JSON data sources. Template functions can both interpolate variables, using
<%= … %>, as well as execute arbitrary Javascript code, with - <% … %>. When you evaluate a template, pass in a - context object that has properties corresponding to the template's free - variables. + <% … %>. When you evaluate a template function, pass in a + context object that has properties corresponding to the template's free + variables. If you're writing a one-off, you can pass the context + object as the second parameter to template in order to render + immediately instead of returning a template function.

 var compiled = _.template("hello: <%= name %>");
diff --git a/test/speed.js b/test/speed.js
index 63cde52bb..5258fb58f 100644
--- a/test/speed.js
+++ b/test/speed.js
@@ -27,8 +27,24 @@
     return _.uniq(numbers, true);
   });
   
+  JSLitmus.test('_.sortBy()', function() {
+    return _.sortBy(numbers, function(num){ return -num; });
+  });
+  
   JSLitmus.test('_.isEqual()', function() {
     return _.isEqual(numbers, randomized);
   });
+  
+  JSLitmus.test('_.keys()', function() {
+    return _.keys(objects);
+  });
+  
+  JSLitmus.test('_.values()', function() {
+    return _.values(objects);
+  });
+  
+  JSLitmus.test('_.intersect()', function() {
+    return _.intersect(numbers, randomized);
+  });
 
 })();
\ No newline at end of file
diff --git a/test/test.html b/test/test.html
index 67415345d..1e001b739 100644
--- a/test/test.html
+++ b/test/test.html
@@ -20,8 +20,14 @@
   


    -

    JSLitmus Speed Suite

    -

    Each iteration runs on an array of 1000 elements.

    +

    Underscore Speed Suite

    +

    + A representative sample of the functions are benchmarked here, to provide + a sense of how fast they might run in different browsers. + Each iteration runs on an array of 1000 elements.

    + For example, the 'intersect' test measures the number of times you can + find the intersection of two thousand-element arrays in one second. +


    \ No newline at end of file diff --git a/underscore.js b/underscore.js index 9f2f403e8..d70ea072d 100644 --- a/underscore.js +++ b/underscore.js @@ -1,12 +1,14 @@ // Underscore.js // (c) 2009 Jeremy Ashkenas, DocumentCloud Inc. // Underscore is freely distributable under the terms of the MIT license. +// Portions of Underscore are inspired by or borrowed from Prototype.js, +// Oliver Steele's Functional, And John Resig's Micro-Templating. // For all details and documentation: -// http://fdjklsafjsdalk +// http://documentcloud.github.com/underscore/ window._ = { VERSION : '0.1.0', - + // The cornerstone, an each implementation. // Handles objects implementing forEach, _each, arrays, and raw objects. each : function(obj, iterator, context) { @@ -243,9 +245,9 @@ window._ = { // passed-in arrays. intersect : function(array) { var rest = _.toArray(arguments).slice(1); - return _.select(_.uniq(array), function(item1) { + return _.select(_.uniq(array), function(item) { return _.all(rest, function(other) { - return _.detect(other, function(item2){ return item1 === item2; }); + return _.indexOf(other, item) >= 0; }); }); },