Imported Upstream version 2.0.0
Thorsten Alteholz
8 years ago
0 | # EditorConfig is awesome: http://EditorConfig.org | |
1 | ||
2 | root = true | |
3 | ||
4 | [*] | |
5 | indent_size = 2 | |
6 | indent_style = space | |
7 | end_of_line = lf | |
8 | charset = utf-8 | |
9 | trim_trailing_whitespace = true | |
10 | insert_final_newline = true |
0 | language: node_js | |
1 | ||
2 | notifications: | |
3 | email: | |
4 | on_success: never | |
5 | on_failure: change | |
6 | ||
7 | node_js: | |
8 | - "0.10" | |
9 | - "4.0" | |
10 | - "4.1" | |
11 | ||
12 | after_script: "npm install coveralls@2 && cat ./coverage/lcov.info | coveralls" |
0 | The MIT License (MIT) | |
1 | ||
2 | Copyright (c) 2014 Blake Embrey (hello@blakeembrey.com) | |
3 | ||
4 | Permission is hereby granted, free of charge, to any person obtaining a copy | |
5 | of this software and associated documentation files (the "Software"), to deal | |
6 | in the Software without restriction, including without limitation the rights | |
7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
8 | copies of the Software, and to permit persons to whom the Software is | |
9 | furnished to do so, subject to the following conditions: | |
10 | ||
11 | The above copyright notice and this permission notice shall be included in | |
12 | all copies or substantial portions of the Software. | |
13 | ||
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
20 | THE SOFTWARE. |
0 | # Array Flatten | |
1 | ||
2 | [![NPM version][npm-image]][npm-url] | |
3 | [![NPM downloads][downloads-image]][downloads-url] | |
4 | [![Build status][travis-image]][travis-url] | |
5 | [![Test coverage][coveralls-image]][coveralls-url] | |
6 | ||
7 | > Flatten nested arrays. | |
8 | ||
9 | ## Installation | |
10 | ||
11 | ``` | |
12 | npm install array-flatten --save | |
13 | ``` | |
14 | ||
15 | ## Usage | |
16 | ||
17 | ```javascript | |
18 | var flatten = require('array-flatten') | |
19 | ||
20 | flatten([1, [2, [3, [4, [5], 6], 7], 8], 9]) | |
21 | //=> [1, 2, 3, 4, 5, 6, 7, 8, 9] | |
22 | ||
23 | flatten.depth([1, [2, [3, [4, [5], 6], 7], 8], 9], 2) | |
24 | //=> [1, 2, 3, [4, [5], 6], 7, 8, 9] | |
25 | ||
26 | (function () { | |
27 | flatten.from(arguments) //=> [1, 2, 3] | |
28 | })(1, [2, 3]) | |
29 | ``` | |
30 | ||
31 | ### Methods | |
32 | ||
33 | * **flatten(array)** Flatten a nested array structure | |
34 | * **flatten.from(arrayish)** Flatten an array-like structure (E.g. arguments) | |
35 | * **flatten.depth(array, depth)** Flatten a nested array structure with a specific depth | |
36 | * **flatten.fromDepth(arrayish, depth)** Flatten an array-like structure with a specific depth | |
37 | ||
38 | ## License | |
39 | ||
40 | MIT | |
41 | ||
42 | [npm-image]: https://img.shields.io/npm/v/array-flatten.svg?style=flat | |
43 | [npm-url]: https://npmjs.org/package/array-flatten | |
44 | [downloads-image]: https://img.shields.io/npm/dm/array-flatten.svg?style=flat | |
45 | [downloads-url]: https://npmjs.org/package/array-flatten | |
46 | [travis-image]: https://img.shields.io/travis/blakeembrey/array-flatten.svg?style=flat | |
47 | [travis-url]: https://travis-ci.org/blakeembrey/array-flatten | |
48 | [coveralls-image]: https://img.shields.io/coveralls/blakeembrey/array-flatten.svg?style=flat | |
49 | [coveralls-url]: https://coveralls.io/r/blakeembrey/array-flatten?branch=master |
0 | 'use strict' | |
1 | ||
2 | /** | |
3 | * Expose `arrayFlatten`. | |
4 | */ | |
5 | module.exports = flatten | |
6 | module.exports.from = flattenFrom | |
7 | module.exports.depth = flattenDepth | |
8 | module.exports.fromDepth = flattenFromDepth | |
9 | ||
10 | /** | |
11 | * Flatten an array. | |
12 | * | |
13 | * @param {Array} array | |
14 | * @return {Array} | |
15 | */ | |
16 | function flatten (array) { | |
17 | if (!Array.isArray(array)) { | |
18 | throw new TypeError('Expected value to be an array') | |
19 | } | |
20 | ||
21 | return flattenFrom(array) | |
22 | } | |
23 | ||
24 | /** | |
25 | * Flatten an array-like structure. | |
26 | * | |
27 | * @param {Array} array | |
28 | * @return {Array} | |
29 | */ | |
30 | function flattenFrom (array) { | |
31 | return flattenDown(array, [], Infinity) | |
32 | } | |
33 | ||
34 | /** | |
35 | * Flatten an array-like structure with depth. | |
36 | * | |
37 | * @param {Array} array | |
38 | * @param {number} depth | |
39 | * @return {Array} | |
40 | */ | |
41 | function flattenDepth (array, depth) { | |
42 | if (!Array.isArray(array)) { | |
43 | throw new TypeError('Expected value to be an array') | |
44 | } | |
45 | ||
46 | return flattenFromDepth(array, depth) | |
47 | } | |
48 | ||
49 | /** | |
50 | * Flatten an array-like structure with depth. | |
51 | * | |
52 | * @param {Array} array | |
53 | * @param {number} depth | |
54 | * @return {Array} | |
55 | */ | |
56 | function flattenFromDepth (array, depth) { | |
57 | if (typeof depth !== 'number') { | |
58 | throw new TypeError('Expected the depth to be a number') | |
59 | } | |
60 | ||
61 | return flattenDownDepth(array, [], depth) | |
62 | } | |
63 | ||
64 | /** | |
65 | * Flatten an array indefinitely. | |
66 | * | |
67 | * @param {Array} array | |
68 | * @param {Array} result | |
69 | * @return {Array} | |
70 | */ | |
71 | function flattenDown (array, result) { | |
72 | for (var i = 0; i < array.length; i++) { | |
73 | var value = array[i] | |
74 | ||
75 | if (Array.isArray(value)) { | |
76 | flattenDown(value, result) | |
77 | } else { | |
78 | result.push(value) | |
79 | } | |
80 | } | |
81 | ||
82 | return result | |
83 | } | |
84 | ||
85 | /** | |
86 | * Flatten an array with depth. | |
87 | * | |
88 | * @param {Array} array | |
89 | * @param {Array} result | |
90 | * @param {number} depth | |
91 | * @return {Array} | |
92 | */ | |
93 | function flattenDownDepth (array, result, depth) { | |
94 | depth-- | |
95 | ||
96 | for (var i = 0; i < array.length; i++) { | |
97 | var value = array[i] | |
98 | ||
99 | if (depth > -1 && Array.isArray(value)) { | |
100 | flattenDownDepth(value, result, depth) | |
101 | } else { | |
102 | result.push(value) | |
103 | } | |
104 | } | |
105 | ||
106 | return result | |
107 | } |
0 | # Benchmarks | |
1 | ||
2 | There are three different types of benchmarks running with associated modules. All are 100% compatible with others in their respective `code/` directory. | |
3 | ||
4 | **Interesting Note:** The fastest `flatten` method, by far, is using `instanceof` instead of `Array.isArray`. As this breaks compatibility across frames, it is not used here. |
0 | var current = require('../../..').from | |
1 | ||
2 | module.exports = args | |
3 | ||
4 | function args () { | |
5 | return current(arguments) | |
6 | } |
0 | var current = require('../../..').from | |
1 | ||
2 | module.exports = loop | |
3 | ||
4 | function loop () { | |
5 | var args = new Array(arguments.length) | |
6 | var len = args.length | |
7 | ||
8 | while (len--) { | |
9 | args[len] = arguments[len] | |
10 | } | |
11 | ||
12 | return current(args) | |
13 | } |
0 | var current = require('../../..').from | |
1 | var _slice = Array.prototype.slice | |
2 | ||
3 | module.exports = slice | |
4 | ||
5 | function slice () { | |
6 | return current(_slice.call(arguments)) | |
7 | } |
0 | module.exports = require('../../..').depth |
0 | module.exports = function (array, depth) { | |
1 | if (depth < 1) { | |
2 | return array | |
3 | } | |
4 | ||
5 | return flatten(array, [], depth || Infinity) | |
6 | } | |
7 | ||
8 | function flatten (array, result, depth) { | |
9 | depth-- | |
10 | ||
11 | var len = array.length | |
12 | var i = 0 | |
13 | ||
14 | while (len--) { | |
15 | if (depth > -1 && Array.isArray(array[i])) { | |
16 | flatten(array[i], result, depth) | |
17 | } else { | |
18 | result.push(array[i]) | |
19 | } | |
20 | ||
21 | i++ | |
22 | } | |
23 | ||
24 | return result | |
25 | } |
0 | module.exports = flatten | |
1 | ||
2 | function flatten (array) { | |
3 | var result = Array.prototype.concat.apply([], array) | |
4 | ||
5 | if (result.length === array.length) { | |
6 | return result | |
7 | } | |
8 | ||
9 | return flatten(result) | |
10 | } |
0 | module.exports = require('../../..') |
0 | module.exports = flatten | |
1 | ||
2 | function flatten (array) { | |
3 | return flattenWithResult(array, []) | |
4 | } | |
5 | ||
6 | function flattenWithResult (array, result) { | |
7 | for (var i = 0; i < array.length; i++) { | |
8 | var value = array[i] | |
9 | ||
10 | if (Array.isArray(value)) { | |
11 | flattenWithResult(value, result) | |
12 | } else { | |
13 | result.push(value) | |
14 | } | |
15 | } | |
16 | ||
17 | return result | |
18 | } |
0 | module.exports = flatten | |
1 | ||
2 | function flatten (array) { | |
3 | return flattenWithResult(array, []) | |
4 | } | |
5 | ||
6 | function flattenWithResult (array, result) { | |
7 | for (var i = 0; i < array.length; i++) { | |
8 | if (Array.isArray(array[i])) { | |
9 | flattenWithResult(array[i], result) | |
10 | } else { | |
11 | result.push(array[i]) | |
12 | } | |
13 | } | |
14 | ||
15 | return result | |
16 | } |
0 | module.exports = flatten | |
1 | ||
2 | function flatten (array, depth) { | |
3 | if (depth == null) { | |
4 | return flattenWithoutDepth(array, []) | |
5 | } | |
6 | ||
7 | return flattenWithDepth(array, [], depth) | |
8 | } | |
9 | ||
10 | function flattenWithoutDepth (array, result) { | |
11 | for (var i = 0; i < array.length; i++) { | |
12 | if (Array.isArray(array[i])) { | |
13 | flattenWithoutDepth(array[i], result) | |
14 | } else { | |
15 | result.push(array[i]) | |
16 | } | |
17 | } | |
18 | ||
19 | return result | |
20 | } | |
21 | ||
22 | function flattenWithDepth (array, result, depth) { | |
23 | for (var i = 0; i < array.length; i++) { | |
24 | if (depth > 0 && Array.isArray(array[i])) { | |
25 | flattenWithDepth(array[i], result, depth - 1) | |
26 | } else { | |
27 | result.push(array[i]) | |
28 | } | |
29 | } | |
30 | ||
31 | return result | |
32 | } |
0 | module.exports = flatten | |
1 | ||
2 | function flatten (array) { | |
3 | var result = [] | |
4 | flattenWithResult(array, result) | |
5 | return result | |
6 | } | |
7 | ||
8 | function flattenWithResult (array, result) { | |
9 | for (var i = 0; i < array.length; i++) { | |
10 | var value = array[i] | |
11 | ||
12 | if (Array.isArray(value)) { | |
13 | flattenWithResult(value, result) | |
14 | } else { | |
15 | result.push(value) | |
16 | } | |
17 | } | |
18 | } |
0 | module.exports = reduce | |
1 | ||
2 | function reduce (array) { | |
3 | return array.reduce(function (acc, value) { | |
4 | if (Array.isArray(value)) { | |
5 | return acc.concat(reduce(value)) | |
6 | } | |
7 | ||
8 | return acc.concat(value) | |
9 | }, []) | |
10 | } |
0 | var _toString = Object.prototype.toString | |
1 | ||
2 | module.exports = flatten | |
3 | ||
4 | function flatten (array) { | |
5 | return flattenWithResult(array, []) | |
6 | } | |
7 | ||
8 | function flattenWithResult (array, result) { | |
9 | for (var i = 0; i < array.length; i++) { | |
10 | if (_toString.call(array[i]) === '[object Array]') { | |
11 | flattenWithResult(array[i], result) | |
12 | } else { | |
13 | result.push(array[i]) | |
14 | } | |
15 | } | |
16 | ||
17 | return result | |
18 | } |
0 | module.exports = flatten | |
1 | ||
2 | function flatten (array) { | |
3 | return flattenWithResult(array, []) | |
4 | } | |
5 | ||
6 | function flattenWithResult (array, result) { | |
7 | var len = array.length | |
8 | var i = -1 | |
9 | ||
10 | while (++i < len) { | |
11 | if (Array.isArray(array[i])) { | |
12 | flattenWithResult(array[i], result) | |
13 | } else { | |
14 | result.push(array[i]) | |
15 | } | |
16 | } | |
17 | ||
18 | return result | |
19 | } |
0 | module.exports = flatten | |
1 | ||
2 | function flatten (array) { | |
3 | return flattenWithResult(array, []) | |
4 | } | |
5 | ||
6 | function flattenWithResult (array, result) { | |
7 | var len = array.length | |
8 | var num = 0 | |
9 | ||
10 | while (len--) { | |
11 | var i = num++ | |
12 | ||
13 | if (Array.isArray(array[i])) { | |
14 | flattenWithResult(array[i], result) | |
15 | } else { | |
16 | result.push(array[i]) | |
17 | } | |
18 | } | |
19 | ||
20 | return result | |
21 | } |
0 | module.exports = flatten | |
1 | ||
2 | function flatten (array) { | |
3 | return flattenWithResult(array, []) | |
4 | } | |
5 | ||
6 | function flattenWithResult (array, result) { | |
7 | var len = array.length | |
8 | ||
9 | while (len) { | |
10 | var i = array.length - len | |
11 | ||
12 | if (Array.isArray(array[i])) { | |
13 | flattenWithResult(array[i], result) | |
14 | } else { | |
15 | result.push(array[i]) | |
16 | } | |
17 | ||
18 | len-- | |
19 | } | |
20 | ||
21 | return result | |
22 | } |
0 | module.exports = flatten | |
1 | ||
2 | function flatten (array) { | |
3 | return flattenWithResult(array, []) | |
4 | } | |
5 | ||
6 | function flattenWithResult (array, result) { | |
7 | var len = array.length | |
8 | var i = 0 | |
9 | ||
10 | while (len--) { | |
11 | if (Array.isArray(array[i])) { | |
12 | flattenWithResult(array[i], result) | |
13 | } else { | |
14 | result.push(array[i]) | |
15 | } | |
16 | ||
17 | i++ | |
18 | } | |
19 | ||
20 | return result | |
21 | } |
0 | module.exports = flatten | |
1 | ||
2 | function flatten (array, depth) { | |
3 | return flattenWithResult(array, [], depth == null ? Infinity : depth) | |
4 | } | |
5 | ||
6 | function flattenWithResult (array, result, depth) { | |
7 | for (var i = 0; i < array.length; i++) { | |
8 | if (depth > 0 && Array.isArray(array[i])) { | |
9 | flattenWithResult(array[i], result, depth - 1) | |
10 | } else { | |
11 | result.push(array[i]) | |
12 | } | |
13 | } | |
14 | ||
15 | return result | |
16 | } |
0 | module.exports = [['a', ['b', ['k', ['a', ['b', ['c'], [['a', [['a', ['b', ['k', ['a', ['b', ['c']], ['a', ['x', ['c'], ['a', ['x', ['k']]], ['d', ['z']]]], ['d', ['m']]], ['d', ['e']]]]], ['d', ['e']]], ['b', ['k', ['a', ['b', ['c']], ['a', ['x', ['c'], ['a', ['x', ['k']]], ['d', ['z']]]], ['d', ['m']]], ['d', ['e']]]]], ['d', ['e']]]], ['a', ['x', ['c'], ['a', ['x', ['k']], [['a', ['b', ['k', ['a', ['b', ['c']], ['a', ['x', ['c'], ['a', ['x', ['k']]], ['d', ['z']]]], ['d', ['m']]], ['d', ['e']]]]], ['d', ['e']]]], ['d', ['z']]]], ['d', ['m']]], ['d', ['e']]]]], 'b', ['d'], [['g']], ['d', ['e']]] |
0 | module.exports = [['a', ['b', ['k', ['a', ['b', ['c']], ['a', ['x', ['c'], ['a', ['x', ['k']]], ['d', ['z']]]], ['d', ['m']]], ['d', ['e']]]]], ['d', ['e']], 'd', ['e', 'z'], 'j'] |
0 | module.exports = [1, 2, 3, 4, 5, 6, 7] |
0 | module.exports = ['a', ['b', ['c', ['d']]], ['e', ['f']], 'h', ['i'], 'j', 'k'] |
0 | var Suite = require('benchmarked') | |
1 | var path = require('path') | |
2 | ||
3 | function name (filename) { | |
4 | return path.basename(path.dirname(filename)) + '/' + path.basename(filename, '.js') | |
5 | } | |
6 | ||
7 | var sample = [1, [2, [3, [4], 3], 2], 1] | |
8 | ||
9 | var flattenSuite = new Suite({ | |
10 | cwd: __dirname, | |
11 | fixtures: 'fixtures/*.js', | |
12 | add: 'code/flatten/*.js', | |
13 | name: name, | |
14 | sample: [sample] | |
15 | }) | |
16 | ||
17 | flattenSuite.run(function (fixture) { | |
18 | return [fixture] | |
19 | }) | |
20 | ||
21 | var argsSuite = new Suite({ | |
22 | cwd: __dirname, | |
23 | fixtures: 'fixtures/*.js', | |
24 | add: 'code/arguments/*.js', | |
25 | name: name, | |
26 | sample: sample | |
27 | }) | |
28 | ||
29 | argsSuite.run() | |
30 | ||
31 | var depthSuite = new Suite({ | |
32 | cwd: __dirname, | |
33 | fixtures: 'fixtures/*.js', | |
34 | add: 'code/depth/*.js', | |
35 | name: name, | |
36 | sample: [sample, 2] | |
37 | }) | |
38 | ||
39 | depthSuite.run(function (fixture) { | |
40 | return [fixture, 4] | |
41 | }) |
0 | { | |
1 | "name": "array-flatten", | |
2 | "version": "2.0.0", | |
3 | "homepage": "https://github.com/blakeembrey/array-flatten", | |
4 | "authors": [ | |
5 | "{{{author}}}" | |
6 | ], | |
7 | "description": "Flatten an array of nested arrays into a single flat array", | |
8 | "main": "array-flatten.js", | |
9 | "keywords": [], | |
10 | "license": "MIT", | |
11 | "ignore": [ | |
12 | "**/.*", | |
13 | "node_modules", | |
14 | "bower_components", | |
15 | "test", | |
16 | "tests" | |
17 | ] | |
18 | } |
0 | { | |
1 | "name": "array-flatten", | |
2 | "version": "2.0.0", | |
3 | "description": "Flatten nested arrays", | |
4 | "main": "array-flatten.js", | |
5 | "files": [ | |
6 | "array-flatten.js", | |
7 | "LICENSE" | |
8 | ], | |
9 | "scripts": { | |
10 | "lint": "standard", | |
11 | "test-spec": "mocha -R spec --bail", | |
12 | "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- -R spec --bail", | |
13 | "test": "npm run lint && npm run test-cov", | |
14 | "benchmark": "node benchmark" | |
15 | }, | |
16 | "repository": { | |
17 | "type": "git", | |
18 | "url": "git://github.com/blakeembrey/array-flatten.git" | |
19 | }, | |
20 | "keywords": [ | |
21 | "array", | |
22 | "flatten", | |
23 | "arguments", | |
24 | "depth", | |
25 | "fast", | |
26 | "for" | |
27 | ], | |
28 | "author": { | |
29 | "name": "Blake Embrey", | |
30 | "email": "hello@blakeembrey.com", | |
31 | "url": "http://blakeembrey.me" | |
32 | }, | |
33 | "license": "MIT", | |
34 | "bugs": { | |
35 | "url": "https://github.com/blakeembrey/array-flatten/issues" | |
36 | }, | |
37 | "homepage": "https://github.com/blakeembrey/array-flatten", | |
38 | "devDependencies": { | |
39 | "benchmarked": "^0.1.4", | |
40 | "istanbul": "^0.4.0", | |
41 | "mocha": "^2.2.4", | |
42 | "pre-commit": "^1.0.7", | |
43 | "standard": "^5.3.1" | |
44 | } | |
45 | } |
0 | /* global describe, it */ | |
1 | ||
2 | var assert = require('assert') | |
3 | var flatten = require('./') | |
4 | ||
5 | describe('array-flatten', function () { | |
6 | describe('flatten', function () { | |
7 | it('should flatten an array', function () { | |
8 | var result = flatten([1, [2, [3, [4, [5]]], 6, [[7], 8], 9], 10]) | |
9 | ||
10 | assert.deepEqual(result, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) | |
11 | }) | |
12 | ||
13 | it('should throw on non-array', function () { | |
14 | assert.throws(function () { | |
15 | flatten('test') | |
16 | }, TypeError) | |
17 | }) | |
18 | ||
19 | it('should work with non-array', function () { | |
20 | var result = flatten.from('test') | |
21 | ||
22 | assert.deepEqual(result, ['t', 'e', 's', 't']) | |
23 | }) | |
24 | }) | |
25 | ||
26 | describe('depth', function () { | |
27 | it('should flatten an array to a specific depth', function () { | |
28 | var result = flatten.depth([1, [2, [3], 4], 5], 1) | |
29 | ||
30 | assert.deepEqual(result, [1, 2, [3], 4, 5]) | |
31 | }) | |
32 | ||
33 | it('should clone an array when no depth is specified', function () { | |
34 | var array = [1, [2, 3]] | |
35 | var clone = flatten.depth(array, 0) | |
36 | ||
37 | assert.ok(clone !== array) | |
38 | assert.deepEqual(clone, array) | |
39 | }) | |
40 | ||
41 | it('should throw on non-array', function () { | |
42 | assert.throws(function () { | |
43 | flatten.depth('test', 10) | |
44 | }, TypeError) | |
45 | }) | |
46 | ||
47 | it('should throw on non-numeric depth', function () { | |
48 | assert.throws(function () { | |
49 | flatten.fromDepth('test', 'test') | |
50 | }, TypeError) | |
51 | }) | |
52 | ||
53 | it('should work with "from"', function () { | |
54 | var result = flatten.fromDepth('test', 1) | |
55 | ||
56 | assert.deepEqual(result, ['t', 'e', 's', 't']) | |
57 | }) | |
58 | }) | |
59 | }) |