├── spec ├── support │ └── jasmine.json └── better_array_spec.js ├── CHANGELOG.md ├── bower.json ├── package.json ├── MIT-LICENSE.txt ├── karma.conf.js ├── better-array.js └── README.md /spec/support/jasmine.json: -------------------------------------------------------------------------------- 1 | { 2 | "spec_dir": "spec", 3 | "spec_files": [ 4 | "**/*[sS]pec.js" 5 | ], 6 | "helpers": [ 7 | "helpers/**/*.js" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## v0.3.1 4 | 5 | * $insert returns updated array 6 | 7 | ## v0.3.0 8 | 9 | * Lots of new methods 10 | * Introduce chaining 11 | * Introduce mutating `$` convention 12 | 13 | ## v0.2.0 14 | 15 | * Rename to BetterArray 16 | * Add new methods: .chain, .or, .unique, .includes, .compact, .times, .count 17 | * .minus returns unique results 18 | * Restrict BetterArrays to only objects that are Array.isArray 19 | 20 | ## v0.1.0 21 | 22 | * Initial release at MMM 1 23 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "better-array", 3 | "main": "better-array.js", 4 | "version": "0.3.1", 5 | "homepage": "https://github.com/janlelis/better-array", 6 | "authors": [ 7 | "Jan Lelis " 8 | ], 9 | "description": "A better API for arrays that you can activate whenever you like. It is a little like an underscore.js, but only for arrays. Inspired by Ruby's core library, but closer to JavaScript's.", 10 | "keywords": [ 11 | "array", 12 | "enumerable", 13 | "operators", 14 | "ruby", 15 | "utils" 16 | ], 17 | "license": "MIT", 18 | "ignore": [ 19 | "**/.*", 20 | "node_modules", 21 | "bower_components", 22 | "spec" 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "better-array", 3 | "version": "0.3.1", 4 | "description": "A better API for arrays that you can activate whenever you like. It is a little like an underscore.js, but only for arrays. Inspired by Ruby's core library, but closer to JavaScript's.", 5 | "homepage": "https://github.com/janlelis/better-array", 6 | "repository": { 7 | "type": "git", 8 | "url": "git://github.com/janlelis/better-array.git" 9 | }, 10 | "keywords": [ 11 | "array", 12 | "enumerable", 13 | "operators", 14 | "ruby", 15 | "utils" 16 | ], 17 | "main": "better-array.js", 18 | "scripts": { 19 | "test": "jasmine && karma start" 20 | }, 21 | "devDependencies": { 22 | "karma": "^0.13.10", 23 | "karma-jasmine": "~0.3", 24 | "karma-chrome-launcher": "^0.2.0", 25 | "karma-firefox-launcher": "^0.1.6", 26 | "jasmine": "~2.3" 27 | }, 28 | "license": "MIT" 29 | } 30 | -------------------------------------------------------------------------------- /MIT-LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 Jan Lelis 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration 2 | // Generated on Fri Jul 18 2014 12:25:00 GMT+0200 (CEST) 3 | 4 | module.exports = function(config) { 5 | config.set({ 6 | 7 | // base path that will be used to resolve all patterns (eg. files, exclude) 8 | basePath: '', 9 | 10 | 11 | // frameworks to use 12 | // available frameworks: https://npmjs.org/browse/keyword/karma-adapter 13 | frameworks: ['jasmine'], 14 | 15 | 16 | // list of files / patterns to load in the browser 17 | files: [ 18 | 'better-array.js', 19 | 'spec/*_spec.js' 20 | ], 21 | 22 | 23 | // list of files to exclude 24 | exclude: [ 25 | ], 26 | 27 | 28 | // preprocess matching files before serving them to the browser 29 | // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor 30 | preprocessors: { 31 | }, 32 | 33 | 34 | // test results reporter to use 35 | // possible values: 'dots', 'progress' 36 | // available reporters: https://npmjs.org/browse/keyword/karma-reporter 37 | reporters: ['dots'], 38 | 39 | 40 | // web server port 41 | port: 9876, 42 | 43 | 44 | // enable / disable colors in the output (reporters and logs) 45 | colors: true, 46 | 47 | 48 | // level of logging 49 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG 50 | logLevel: config.LOG_INFO, 51 | 52 | 53 | // enable / disable watching file and executing tests whenever any file changes 54 | autoWatch: false, 55 | 56 | 57 | // start these browsers 58 | // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher 59 | browsers: [process.env.TRAVIS ? 'Chrome_travis_ci' : 'Chrome', 'Firefox'], 60 | customLaunchers: { 61 | Chrome_travis_ci: { 62 | base: 'Chrome', 63 | flags: ['--no-sandbox'] 64 | } 65 | }, 66 | 67 | // Continuous Integration mode 68 | // if true, Karma captures browsers, runs the tests and exits 69 | singleRun: true 70 | }); 71 | }; 72 | -------------------------------------------------------------------------------- /better-array.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | (function(global, code){ 4 | if(typeof exports === 'object'){ 5 | module.exports = code(); 6 | } else{ 7 | global.BetterArray = code(); 8 | }}(this, function(){ 9 | 10 | var BetterArray = function BetterArray(array){ 11 | var newBetterArray = Object.create(BetterArrayPrototype); 12 | newBetterArray.native = array; 13 | return newBetterArray; 14 | } 15 | 16 | var BetterArrayPrototype = { 17 | and: function and(other){ 18 | return this.native.filter(function(e){ 19 | return other.indexOf(e) >= 0; 20 | }); 21 | }, 22 | at: function at(index){ 23 | if(arguments.length === 1){ 24 | return this.native[index]; 25 | } else { 26 | return Array.prototype.map.call(arguments, function(i){ 27 | return this.native[i]; 28 | }.bind(this)); 29 | } 30 | }, 31 | $clear: function $clear(){ 32 | this.native.length = 0; 33 | return this.native; 34 | }, 35 | clone: function clone(){ 36 | return this.native.slice(); 37 | }, 38 | compact: function compact(){ 39 | return this.native.filter(function(e){ 40 | return e != null; 41 | }); 42 | }, 43 | contains: function contains(element){ 44 | return this.native.indexOf(element) >= 0; 45 | }, 46 | count: function count(object){ 47 | if(arguments.length === 0){ 48 | return this.native.length; 49 | } else { 50 | return this.native.filter(function(e){ return e === object }).length; 51 | } 52 | }, 53 | $delete: function $delete(indexes){ 54 | var indexesToDelete = Array.prototype.slice.call(arguments).sort().reverse(); 55 | for(var i = 0; i < indexesToDelete.length; i++){ 56 | this.native.splice(indexesToDelete[i], 1); 57 | } 58 | return this.native; 59 | }, 60 | doesEvery: function doesEvery(){ 61 | return this.native.every.apply(this.native, arguments); 62 | }, 63 | doesSome: function doesSome(){ 64 | return this.native.some.apply(this.native, arguments); 65 | }, 66 | doesNone: function doesNone(fn){ 67 | return this.native.every.call(this.native, function(e){ return !fn(e); }); 68 | }, 69 | each: function each(){ 70 | return this.native.forEach.apply(this.native, arguments); 71 | }, 72 | filter: function filter(){ 73 | return this.native.filter.apply(this.native, arguments); 74 | }, 75 | first: function first(number){ 76 | if(arguments.length === 0){ 77 | return this.native[0]; 78 | } else { 79 | return this.native.slice(0, number); 80 | } 81 | }, 82 | grep: function grep(matcher){ 83 | return this.native.filter(function(e){ 84 | return matcher.test(e) 85 | }); 86 | }, 87 | indexOf: function indexOf(){ 88 | return this.native.indexOf.apply(this.native, arguments); 89 | }, 90 | $insert: function $insert(index, element){ 91 | this.native.splice(index, 0, element); 92 | return this.native; 93 | }, 94 | isEmpty: function isEmpty(){ 95 | return this.native.length === 0; 96 | }, 97 | last: function last(number){ 98 | if(arguments.length === 0){ 99 | return this.native[this.native.length - 1]; 100 | } else { 101 | return this.native.slice(-number, this.native.length); 102 | } 103 | }, 104 | lastIndexOf: function lastIndexOf(){ 105 | return this.native.lastIndexOf.apply(this.native, arguments); 106 | }, 107 | map: function map(){ 108 | return this.native.map.apply(this.native, arguments); 109 | }, 110 | minus: function minus(other){ 111 | return BetterArray( 112 | this.native.filter(function(e){ 113 | return other.indexOf(e) < 0; 114 | }) 115 | ).unique(); 116 | }, 117 | or: function or(other){ 118 | return BetterArray(this.native.concat(other)).unique(); 119 | }, 120 | plus: function plus(other){ 121 | return this.native.concat(other); 122 | }, 123 | $pop: function $pop(){ 124 | return this.native.pop.apply(this.native, arguments); 125 | }, 126 | $push: function $push(){ 127 | return this.native.push.apply(this.native, arguments); 128 | }, 129 | reduce: function reduce(){ 130 | return this.native.reduce.apply(this.native, arguments); 131 | }, 132 | reduceRight: function reduceRight(){ 133 | return this.native.reduceRight.apply(this.native, arguments); 134 | }, 135 | reverse: function reverse(){ 136 | var clone = this.native.slice(); 137 | return clone.reverse.apply(clone, arguments); 138 | }, 139 | $reverse: function $reverse(){ 140 | return this.native.reverse.apply(this.native, arguments); 141 | }, 142 | rotate: function rotate(count){ 143 | if(arguments.length === 0){ count = 1 } 144 | return this.native.slice(count, this.native.length).concat(this.native.slice(0, count)); 145 | }, 146 | $set: function $set(index, element){ 147 | this.native[index] = element; 148 | return this.native; 149 | }, 150 | size: function size(){ 151 | return this.native.length; 152 | }, 153 | $shift: function $shift(){ 154 | return this.native.shift.apply(this.native, arguments); 155 | }, 156 | slice: function slice(){ 157 | return this.native.slice.apply(this.native, arguments); 158 | }, 159 | sliceLength: function sliceLength(from, length){ 160 | return this.native.slice(from, from + length); 161 | }, 162 | sort: function sort(){ 163 | var clone = this.native.slice(); 164 | return clone.sort.apply(clone, arguments); 165 | }, 166 | $sort: function $sort(){ 167 | return this.native.sort.apply( this.native, arguments); 168 | }, 169 | $splice: function $splice(){ 170 | return this.native.splice.apply(this.native, arguments); 171 | }, 172 | times: function times(integer){ 173 | var res = [] 174 | for(var i = 0; i < integer; i++){ 175 | res = res.concat(this.native); 176 | } 177 | return res; 178 | }, 179 | toArray: function toArray(){ 180 | return this.native; 181 | }, 182 | unique: function unique(){ 183 | return this.native.filter(function(e){ 184 | return e in this ? false : this[e] = true; 185 | }, {}); 186 | }, 187 | $unshift: function $unshift(){ 188 | return this.native.unshift.apply(this.native, arguments); 189 | }, 190 | withoutFirst: function withoutFirst(number){ 191 | if(arguments.length === 0){ number = 1; } 192 | return this.native.slice(number, this.native.length); 193 | }, 194 | withoutLast: function withoutLast(number){ 195 | if(arguments.length === 0){ number = 1; } 196 | return this.native.slice(0, this.native.length - number); 197 | }, 198 | zip: function zip(){ 199 | var others = Array.prototype.slice.call(arguments); 200 | return this.native.map(function(e, i) { 201 | var row = others.map(function(f){ return f[i]; }); 202 | row.unshift(e); 203 | return row; 204 | }); 205 | } 206 | } 207 | 208 | // Allow some chaining 209 | 210 | var BetterArrayChainPrototype = {}; 211 | 212 | for(var functionName in BetterArrayPrototype){ 213 | (function(){ 214 | var fn = BetterArrayPrototype[functionName]; 215 | if(functionName === "toArray"){ 216 | BetterArrayChainPrototype[functionName] = fn; 217 | } else { 218 | BetterArrayChainPrototype[functionName] = function chain(){ 219 | return BetterArray.chain(fn.apply(this, arguments)); 220 | } 221 | } 222 | })(); 223 | } 224 | 225 | BetterArray.chain = function BetterArrayChain(array){ 226 | var newBetterArrayChain = Object.create(BetterArrayChainPrototype); 227 | newBetterArrayChain.native = array; 228 | return newBetterArrayChain; 229 | } 230 | 231 | return BetterArray; 232 | }) 233 | ); 234 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BetterArray for JavaScript 2 | 3 | A better API for arrays that you can activate whenever you like. It is a little like an underscore.js, but only for arrays. Inspired by Ruby's core library, but closer to JavaScript's. 4 | 5 | **Discontinued:**: This project was great to learn more about arrays in JavaScript coming from Ruby. You are encouraged to check [the source](https://github.com/janlelis/better-array/blob/master/better-array.js) to learn about the implementation of each method. 6 | 7 | ## How it Works 8 | 9 | ```javascript 10 | var BetterArray = require('better-array'); // if node/commonjs 11 | ``` 12 | 13 | You feed your arrays into the `BetterArray()` function: 14 | 15 | ```javascript 16 | var a = BetterArray([3, "b", 4, null, 5, "b", 0]); 17 | ``` 18 | 19 | Now, `a` is a BetterArray object and has access to all the wonderful methods below. For example, `compact`, which removes all `null` and `undefined` elements: 20 | 21 | ```javascript 22 | a.compact(); // => [3, 'b', 4, 5, "b", 0] 23 | ``` 24 | 25 | Please note that the resulting objects are always vanilla JS objects, not BetterArray wrapper objects. This is intentional; the main goal of this library is not the ability to chain, but to be very unobtrusive. 26 | 27 | ## Design Goals 28 | 29 | * Good API over performance 30 | * Delegate to native functions whenever possible 31 | * Don't extend `Array.prototype` 32 | 33 | ## Install 34 | 35 | Use the script file directly (via the `BetterArray` browser global), or get it from npm: 36 | 37 | $ npm install better-array 38 | 39 | ## Examples 40 | 41 | ```javascript 42 | $ node 43 | > ba = require('better-array') 44 | > array = ba([2, 3, 4, 4, 5]) 45 | > array.first() 46 | 2 47 | > array.last() 48 | 5 49 | > array.last(3) 50 | [ 4, 4, 5 ] 51 | > array.minus([3, 4]) 52 | [ 2, 5 ] 53 | > array.or([4, 5, 6]) 54 | [ 2, 3, 4, 5, 6 ] 55 | > array.unique() 56 | [ 2, 3, 4, 5 ] 57 | > array.count(4) 58 | 2 59 | > array.contains(9) 60 | false 61 | > array.isEmpty() 62 | false 63 | > array.doesSome(function(e){ return e % 2 == 0 }) 64 | true 65 | > array.doesEvery(function(e){ return e % 2 == 0 }) 66 | false 67 | > array.doesNone(function(e){ return e % 2 == 0 }) 68 | false 69 | > array.$insert(2, "new element"); 70 | // array is now [2, 3, 'new element', 4, 4, 5 ] 71 | ``` 72 | 73 | See [better_array_spec](https://github.com/janlelis/better-array/blob/master/spec/better_array_spec.js) for more examples! 74 | 75 | ## API 76 | 77 | All methods that begin with `$` mutate the original array, the others don't. 78 | 79 | Method | Description 80 | -------|------------ 81 | `.and(array)` | Returns the intersection: Keep only values which can be found in both arrays 82 | `.at(index)` | Returns value at this index. Returns an array with the values when given multiple arguments 83 | `.$clear()` | Deletes all content from the array and returns the emptied array 84 | `.clone()` | Returns a new array object referencing the same values 85 | `.compact()` | Returns array with all `null` and `undefined` values removed. Note that this is different from underscore's version, which removes all *falsy* values. 86 | `.contains()` | Returns boolean that indicates if the element is part of the array 87 | `.count()` | Returns number of elements. If argument given, returns how often this object appears(using `===`) 88 | `.$delete(index)` | Remove the element at the given index. Can take multiple arguments. 89 | `.doesEvery()` | [Array.prototype.every](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every) 90 | `.doesSome()` | [Array.prototype.some](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some) 91 | `.doesNone()` | Returns true if none of the elements returns a true value for the test function 92 | `.each()` | [Array.prototype.forEach](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach) 93 | `.filter()` | [Array.prototype.filter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) 94 | `.first()` | Returns the first element 95 | `.grep()` | Returns an array of elements matching the (regex) test 96 | `.first(integer)` | Returns an array of the first N elements 97 | `.grep(matcher)` | Returns a filtered array by calling `matcher.test()` on every element, so you can use it to filter an array of strings using a regex 98 | `.indexOf()` | [Array.prototype.indexOf](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf) 99 | `.$insert(index, value)` | Inserts an new element at this position 100 | `.isEmpty()` | Returns `true` if the array is empty 101 | `.last()` | Returns the last element. Returns an array of the last N elements if an integer argument given 102 | `.lastIndexOf()` | [Array.prototype.lastIndexOf](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/lastIndexOf) 103 | `.map()` | [Array.prototype.map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) 104 | `.minus(array)` | Returns an array with unique values and all elements of the other array removed 105 | `.or(array)` | Returns a unique array out of all elements of both arrays 106 | `.plus(array)` | Returns a concatenated array 107 | `.$pop()` | [Array.prototype.pop](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/pop) 108 | `.$push()` | [Array.prototype.push](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push) 109 | `.reduce()` | [Array.prototype.reduce](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce) 110 | `.reduceRight()` | [Array.prototype.reduceRight](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduceRight) 111 | `.reverse()` | Returns the reversed array 112 | `.$reverse()` | [Array.prototype.reverse](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse) 113 | `.rotate()` | Returns an array with the first element(s) put at the end 114 | `.$set(index, value)` | Sets the value at the given index 115 | `.size()` | Returns the array length 116 | `.$shift()` | [Array.prototype.shift](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/shift) 117 | `.slice()` | [Array.prototype.slice](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice) 118 | `.sliceLength(index, length)` | Returns an array slice, but second parameter determines length instead of end position 119 | `.sort()` | Returns the array with all elements sorted 120 | `.$sort()` | [Array.prototype.sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) 121 | `.$splice()` | [Array.prototype.splice](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice) 122 | `.times(integer)` | Repeats the array N times 123 | `.toArray()` | Returns the underlying array 124 | `.unique()` | Returns array with no double entries 125 | `.$unshift()` | [Array.prototype.unshift](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/unshift) 126 | `.withoutFirst(number)` | Returns an array without the first N elements 127 | `.withoutLast(number)` | Returns an array without the last N elements 128 | `.zip(*arrays)` | Returns the transposed array 129 | 130 | ## Chaining 131 | 132 | You have two options to chain together multiple better array functions: 133 | 134 | ### Using `BetterArray.chain` (more magic) 135 | 136 | ```javascript 137 | BetterArray.chain([2, null, 3, 4]).withoutLast().compact().toArray() // => [2, 3] 138 | ``` 139 | 140 | ### Extending the `Array.prototype` yourself (more explicit) 141 | 142 | ```javascript 143 | Array.prototype.betterArray = function betterArray(){ 144 | return BetterArray(this); 145 | } 146 | ``` 147 | 148 | Use it like this: 149 | 150 | ```javascript 151 | BetterArray([2, null, 3, 4]).withoutLast().betterArray().compact() // => [2, 3] 152 | ``` 153 | 154 | ## Wish List 155 | 156 | Not implemented, yet: 157 | 158 | * xor 159 | * eachRight 160 | * mapRight 161 | * $deleteValue 162 | * isEqual 163 | * find 164 | * findIndex 165 | * $fill 166 | * fetch 167 | * flatten 168 | * reject 169 | * sample 170 | * shuffle 171 | * $shuffle 172 | * groupBy 173 | * eachWindow (each_slice) 174 | * eachGroupOf (each_cons) 175 | * eachWithObject 176 | * cycle 177 | * min 178 | * max 179 | * minmax 180 | 181 | ## MIT License 182 | 183 | Copyright (C) 2015 Jan Lelis. Released under the MIT license. 184 | -------------------------------------------------------------------------------- /spec/better_array_spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | if (typeof(BetterArray) === 'undefined') { 4 | var isNode = true; 5 | var ba = require("../better-array"); 6 | } else { 7 | var isNode = false; 8 | var ba = BetterArray; 9 | } 10 | 11 | describe('BetterArray', function() { 12 | describe('.and', function() { 13 | it("returns the intersection", function() { 14 | expect( ba([2, 3, 4]).and([3, 4, 5]) ).toEqual([3, 4]); 15 | }); 16 | }); 17 | 18 | describe('.at', function() { 19 | it("returns value at that index for one argument", function() { 20 | expect( ba([2, 3, 4]).at(1) ).toEqual(3); 21 | }); 22 | 23 | it("returns values at that indexes for multiple arguments", function() { 24 | expect( ba([2, 3, 4]).at(0, 2) ).toEqual([2, 4]); 25 | }); 26 | }); 27 | 28 | describe('.$clear', function() { 29 | it("deletes all content from the array", function() { 30 | var array = [2, 3, 4]; 31 | ba(array).$clear(); 32 | expect( array ).toEqual([]); 33 | }); 34 | 35 | it("returns the empty array", function(){ 36 | var array = [2, 3, 4]; 37 | expect( ba(array).$clear() ).toEqual([]); 38 | }); 39 | }); 40 | 41 | describe('.clone', function() { 42 | it("returns a shallow copy of the array", function() { 43 | var object = [2, 3, 4]; 44 | expect( ba(object).clone() ).toEqual(object); 45 | }); 46 | 47 | it("returns a different object", function() { 48 | var object = [2, 3, 4]; 49 | expect( ba(object).clone() ).not.toBe(object); 50 | }); 51 | }); 52 | 53 | describe('.compact', function() { 54 | it("returns array with all null and undefined values removed", function() { 55 | expect( ba([2, null, 3, undefined, 4, false]).compact() ).toEqual([2, 3, 4, false]); 56 | }); 57 | }); 58 | 59 | describe('.contains', function() { 60 | it("checks if an element is included in the array", function() { 61 | expect( ba([2, 3, 4]).contains(4) ).toEqual(true); 62 | expect( ba([2, 3, 4]).contains(5) ).toEqual(false); 63 | }); 64 | }); 65 | 66 | describe('.count', function() { 67 | it("returns array size for no argument", function() { 68 | expect( ba([2, 3, 4]).count() ).toEqual(3); 69 | }); 70 | 71 | it("returns number of === matches for one argument", function() { 72 | expect( ba([2, 3, 3, 4]).count(3) ).toEqual(2); 73 | }); 74 | }); 75 | 76 | describe('.$delete', function() { 77 | it("deletes the element at the given index", function() { 78 | var array = [2, 3, 4]; 79 | ba(array).$delete(1); 80 | expect( array ).toEqual([2, 4]); 81 | }); 82 | 83 | it("can delete multiple elements at once", function() { 84 | var array = [2, 3, 4]; 85 | ba(array).$delete(0, 2); 86 | expect( array ).toEqual([3]); 87 | }); 88 | 89 | it("returns the array", function(){ 90 | var array = [2, 3, 4]; 91 | expect( ba(array).$delete(0, 2) ).toEqual([3]); 92 | }); 93 | }); 94 | 95 | describe('.doesEvery', function() { 96 | it("delegates to native .every", function() { 97 | expect( ba([2, 3, 4]).doesEvery(function(e){ return e % 2 == 0; }) ).toEqual(false); 98 | expect( ba([2, 3, 4]).doesEvery(function(e){ return e % 1 == 0; }) ).toEqual(true); 99 | }); 100 | }); 101 | 102 | describe('.doesNone', function() { 103 | it("returns true if none of the elements returns a true value for the test function", function() { 104 | expect( ba([2, 3, 4]).doesNone(function(e){ return e % 5 == 0; }) ).toEqual(true); 105 | }); 106 | 107 | it("returns false if at least one of the elements returns a true value for the test function", function() { 108 | expect( ba([2, 3, 4]).doesNone(function(e){ return e % 4 == 0; }) ).toEqual(false); 109 | }); 110 | }); 111 | 112 | describe('.doesSome', function() { 113 | it("delegates to native .some", function() { 114 | expect( ba([2, 3, 4]).doesSome(function(e){ return e % 5 == 0; }) ).toEqual(false); 115 | expect( ba([2, 3, 4]).doesSome(function(e){ return e % 4 == 0; }) ).toEqual(true); 116 | }); 117 | }); 118 | 119 | describe('.each', function() { 120 | it("delegates to native .forEach", function() { 121 | var res = []; 122 | ba([2, 3, 4]).each(function(e, i){ res[i] = e + 1; }) 123 | expect( res ).toEqual([3, 4, 5]); 124 | }); 125 | }); 126 | 127 | describe('.filter', function() { 128 | it("delegates to native .filter", function() { 129 | expect( 130 | ba([2, 3, 4]).filter(function(e){ return e % 2 === 0; }) 131 | ).toEqual([2, 4]); 132 | }); 133 | }); 134 | 135 | describe('.first', function() { 136 | it("returns the first value for no argument", function() { 137 | expect( ba([2, 3, 4]).first() ).toEqual(2); 138 | }); 139 | 140 | it("returns the first N values for integer argument", function() { 141 | expect( ba([2, 3, 4]).first(2) ).toEqual([2, 3]); 142 | }); 143 | }); 144 | 145 | describe('.grep', function() { 146 | it("returns an array of elements matching the (regex) test ", function() { 147 | expect( ba(["More", "Micro", "Modules"]).grep(/r/) ).toEqual(["More", "Micro"]); 148 | }); 149 | }); 150 | 151 | describe('.indexOf', function() { 152 | it("delegates to native .indexOf", function() { 153 | expect( ba([2, 3, 3, 4]).indexOf(3) ).toEqual(1); 154 | }); 155 | }); 156 | 157 | describe('.$insert', function() { 158 | it("inserts a new element into the array", function() { 159 | var array = [2, 3, 4]; 160 | ba(array).$insert(1, 2.5); 161 | expect( array ).toEqual([2, 2.5, 3, 4]); 162 | }); 163 | 164 | it("returns the updated array", function() { 165 | var array = [2, 3, 4]; 166 | expect( ba(array).$insert(1, 2.5) ).toEqual([2, 2.5, 3, 4]); 167 | }); 168 | }); 169 | 170 | describe('.isEmpty', function() { 171 | it("returns false for non-empty arrays ", function() { 172 | expect( ba([2, 3, 4]).isEmpty() ).toEqual(false); 173 | }); 174 | 175 | it("returns true for empty arrays ", function() { 176 | expect( ba([]).isEmpty() ).toEqual(true); 177 | }); 178 | }); 179 | 180 | describe('.last', function() { 181 | it("returns the last value for no argument", function() { 182 | expect( ba([2, 3, 4]).last() ).toEqual(4); 183 | }); 184 | 185 | it("returns the last N values for integer argument", function() { 186 | expect( ba([2, 3, 4]).last(2) ).toEqual([3, 4]); 187 | }); 188 | }); 189 | 190 | describe('.lastIndexOf', function() { 191 | it("delegates to native .lastIndexOf", function() { 192 | expect( ba([2, 3, 3, 4]).indexOf(3) ).toEqual(1); 193 | }); 194 | }); 195 | 196 | describe('.map', function() { 197 | it("delegates to native .map", function() { 198 | expect( 199 | ba([2, 3, 4]).map(function(e){ return e + 1; }) 200 | ).toEqual([3, 4, 5]); 201 | }); 202 | }); 203 | 204 | describe('.minus', function() { 205 | it("takes values from array without the ones from the other array", function() { 206 | expect( ba([2, 3, 4] ).minus([3, 4, 5]) ).toEqual([2]); 207 | }); 208 | }); 209 | 210 | describe('.or', function() { 211 | it("returns a uniqe array out of all elements of both arrays", function() { 212 | expect( ba([2, 3, 4] ).or([3, 4, 4, 5]) ).toEqual([2, 3, 4, 5]); 213 | }); 214 | }); 215 | 216 | describe('.plus', function() { 217 | it("concatenates two arrays", function() { 218 | expect( ba([2, 3, 4]).plus([3, 4, 5]) ).toEqual([2, 3, 4, 3, 4, 5]); 219 | }); 220 | }); 221 | 222 | describe('.$pop', function(){ 223 | it("removes an element from the end of the array", function(){ 224 | var array = [2, 3, 4]; 225 | ba(array).$pop(); 226 | expect( array ).toEqual([2, 3]); 227 | }); 228 | 229 | it("returns the removed element", function(){ 230 | var array = [2, 3, 4]; 231 | expect( ba(array).$pop() ).toEqual(4); 232 | }); 233 | }); 234 | 235 | describe('.$push', function(){ 236 | it("appends an element to the end of the array", function(){ 237 | var array = [2, 3, 4]; 238 | ba(array).$push(5); 239 | expect( array ).toEqual([2, 3, 4, 5]); 240 | }); 241 | 242 | it("returns the new array length", function(){ 243 | var array = [2, 3, 4]; 244 | expect( ba(array).$push(5) ).toEqual(4); 245 | }); 246 | }); 247 | 248 | describe('.reduce', function() { 249 | it("delegates to native .reduce", function() { 250 | expect( 251 | ba([2, 3, 4]).reduce(function(acc, cur){ return acc - cur; }) 252 | ).toEqual(-5); 253 | }); 254 | }); 255 | 256 | describe('.reduceRight', function() { 257 | it("delegates to native .reduceRight", function() { 258 | expect( 259 | ba([2, 3, 4]).reduceRight(function(acc, cur){ return acc - cur; }) 260 | ).toEqual(-1); 261 | }); 262 | }); 263 | 264 | describe('.reverse', function() { 265 | it("delegates to native .reverse", function() { 266 | expect( ba([2, 3, 4]).reverse() ).toEqual([4, 3, 2]) 267 | }); 268 | 269 | it("does not mutate the original array", function() { 270 | var object = [2, 3, 4]; 271 | ba(object).reverse(); 272 | expect(object).toEqual([2, 3, 4]); 273 | }); 274 | }); 275 | 276 | describe('.$reverse', function() { 277 | it("delegates to native .reverse", function() { 278 | expect( ba([2, 3, 4]).$reverse() ).toEqual([4, 3, 2]) 279 | }); 280 | 281 | it("does mutate the original array", function() { 282 | var object = [2, 3, 4]; 283 | ba(object).$reverse(); 284 | expect(object).toEqual([4, 3, 2]); 285 | }); 286 | }); 287 | 288 | describe('.rotate', function() { 289 | it("rotates by N", function() { 290 | expect( ba([2, 3, 4, 5, 6]).rotate(2) ).toEqual([4, 5, 6, 2, 3]); 291 | }); 292 | 293 | it("rotates by negative N", function() { 294 | expect( ba([2, 3, 4, 5, 6]).rotate(-2) ).toEqual([5, 6, 2, 3, 4]); 295 | }); 296 | 297 | it("rotates by 1 without argument", function() { 298 | expect( ba([2, 3, 4, 5, 6]).rotate() ).toEqual([3, 4, 5, 6, 2]); 299 | }); 300 | }); 301 | 302 | describe('.$set', function() { 303 | it("sets the element at this index and returns array", function() { 304 | var array = [2, 3, 4]; 305 | ba(array).$set(1, "three") 306 | expect( array ).toEqual([2, "three", 4]); 307 | }); 308 | 309 | it("returns updated array", function() { 310 | expect( ba([2, 3, 4]).$set(1, "three") ).toEqual([2, "three", 4]); 311 | }); 312 | }); 313 | 314 | describe('.size', function() { 315 | it("returns array size ", function() { 316 | expect( ba([2, 3, 4]).size() ).toEqual(3); 317 | }); 318 | }); 319 | 320 | describe('.$shift', function(){ 321 | it("removes an element from the beginning of the array", function(){ 322 | var array = [2, 3, 4]; 323 | ba(array).$shift(); 324 | expect( array ).toEqual([3, 4]); 325 | }); 326 | 327 | it("returns the removed element", function(){ 328 | var array = [2, 3, 4]; 329 | expect( ba(array).$shift() ).toEqual(2); 330 | }); 331 | }); 332 | 333 | describe('.slice', function() { 334 | it("returns a the slice, 2nd params defines end index", function() { 335 | expect( ba([2, 3, 4]).slice(1,2) ).toEqual([3]); 336 | }); 337 | }); 338 | 339 | describe('.sliceLength', function() { 340 | it("returns a the slice, but 2nd params defines length of slice", function() { 341 | expect( ba([2, 3, 4]).sliceLength(1,2) ).toEqual([3, 4]); 342 | }); 343 | }); 344 | 345 | describe('.sort', function() { 346 | it("delegates to native .sort", function() { 347 | expect( ba([4, 3, 2]).sort() ).toEqual([2, 3, 4]) 348 | }); 349 | 350 | it("does not mutate the original array", function() { 351 | var object = [4, 3, 2]; 352 | ba(object).sort(); 353 | expect(object).toEqual([4, 3, 2]); 354 | }); 355 | }); 356 | 357 | describe('.$sort', function() { 358 | it("delegates to native .sort", function() { 359 | expect( ba([4, 3, 2]).$sort() ).toEqual([2, 3, 4]) 360 | }); 361 | 362 | it("does mutate the original array", function() { 363 | var object = [4, 3, 2]; 364 | ba(object).$sort(); 365 | expect(object).toEqual([2, 3, 4]); 366 | }); 367 | }); 368 | 369 | describe('.$splice', function() { 370 | it("returns a the slice", function() { 371 | expect( ba([2, 3, 4]).$splice(1, 2) ).toEqual([3, 4]); 372 | }); 373 | 374 | it("removes slice from original array", function() { 375 | var array = [2, 3, 4]; 376 | ba(array).$splice(1, 2); 377 | expect( array ).toEqual([2]); 378 | }); 379 | 380 | it("can be used to add new content to the array", function(){ 381 | var array = [2, 3, 4]; 382 | ba(array).$splice(1, 2, 0); 383 | expect( array ).toEqual([2, 0]); 384 | }); 385 | }); 386 | 387 | describe('.times', function() { 388 | it("returns an array N times repeated", function() { 389 | expect( ba([2, 3, 4]).times(3) ).toEqual([2, 3, 4, 2, 3, 4, 2, 3, 4]); 390 | }); 391 | }); 392 | 393 | describe('.toArray', function() { 394 | it("returns native array", function() { 395 | var object = [2, 3, 4]; 396 | expect( ba(object).toArray() ).toBe(object); 397 | }); 398 | }); 399 | 400 | describe('.unique', function() { 401 | it("returns array with no double entries", function() { 402 | expect( ba([2, 3, 3, 4]).unique() ).toEqual([2, 3, 4]); 403 | }); 404 | }); 405 | 406 | describe('.$unshift', function(){ 407 | it("appends an element to the beginning of the array", function(){ 408 | var array = [2, 3, 4]; 409 | ba(array).$unshift(5); 410 | expect( array ).toEqual([5, 2, 3, 4]); 411 | }); 412 | 413 | it("returns the new array length", function(){ 414 | var array = [2, 3, 4]; 415 | expect( ba(array).$unshift(5) ).toEqual(4); 416 | }); 417 | }); 418 | 419 | describe('.withoutFirst', function(number) { 420 | it("returns the all of the arrays values, except the first N", function() { 421 | expect( ba([2, 3, 4]).withoutFirst(2) ).toEqual([4]); 422 | }); 423 | 424 | it("assumes count of 1 when no argument given", function() { 425 | expect( ba([2, 3, 4]).withoutFirst() ).toEqual([3, 4]); 426 | }); 427 | }); 428 | 429 | describe('.withoutLast', function(number) { 430 | it("returns the all of the arrays values, except the last N", function() { 431 | expect( ba([2, 3, 4]).withoutLast(2) ).toEqual([2]); 432 | }); 433 | 434 | it("assumes count of 1 when no argument given", function() { 435 | expect( ba([2, 3, 4]).withoutLast() ).toEqual([2, 3]); 436 | }); 437 | }); 438 | 439 | describe('.zip', function() { 440 | it("zips together multilpe arrays", function() { 441 | expect( 442 | ba([2, 3, 4]).zip([9, 8, 7], ["a", "b", "c"]) 443 | ).toEqual( 444 | [ 445 | [2, 9, "a"], 446 | [3, 8, "b"], 447 | [4, 7, "c"] 448 | ] 449 | ); 450 | }); 451 | }); 452 | 453 | describe('[chaining]', function(){ 454 | it("works", function(){ 455 | expect( 456 | ba.chain([2, 3, null, 4]).reverse().compact().toArray() 457 | ).toEqual([4, 3, 2]); 458 | }); 459 | 460 | it("returns an Array for .toArray()", function(){ 461 | expect( 462 | Array.isArray( ba.chain([2, 3, 4]).reverse().toArray() ) 463 | ).toEqual(true); 464 | }); 465 | }); 466 | 467 | }); 468 | --------------------------------------------------------------------------------