Passed
Push — master ( 384951...232346 )
by Eric
01:15
created

utilities.js ➔ ... ➔ mapBy.map   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
/*!
2
 * utilities.js | v0.9.0 | Utility functions for front-end JavaScript development
3
 * Copyright (c) 2017 Eric Zieger (MIT license)
4
 * https://github.com/theZieger/utilitiesjs/blob/master/LICENSE
5
 */
6 1
(function(root, factory) {
7
    /** global: define */
8 4
    if (typeof define === "function" && define.amd) {
9
        define('utilitiesjs', factory);
10
    /** global: module */
11 4
    } else if (typeof module === "object" && module.exports) {
12 1
        module.exports = factory();
13
    } else {
14
        root.utilities = factory();
15
    }
16
}(this, function(undefined) {
17
18
    /**
19
     * inherit the prototype of the SuperConstructor
20
     *
21
     * Warning: Changing the prototype of an object is, by the nature of how
22
     * modern JavaScript engines optimize property accesses, a very slow
23
     * operation, in every browser and JavaScript engine. So instead of using
24
     * Object.setPrototypeOf or messing with __proto__, we create a new object
25
     * with the desired prototype using Object.create().
26
     *
27
     * @see https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf
28
     *
29
     * @param {Object} Constructor
30
     * @param {Object} SuperConstructor
31
     *
32
     * @throws {TypeError} if arguments are `null`, `undefined`, or
33
     *                     `SuperConstructor` has no prototype
34
     *
35
     * @returns {Void}
36
     */
37 1
    var inherits = function(Constructor, SuperConstructor) {
38 6
        if (Constructor === undefined || Constructor === null) {
39 2
            throw new TypeError('Constructor argument is undefined or null');
40
        }
41
42 4
        if (SuperConstructor === undefined || SuperConstructor === null) {
43 2
            throw new TypeError('SuperConstructor argument is undefined or null');
44
        }
45
46 2
        if (SuperConstructor.prototype === undefined) {
47 1
            throw new TypeError('SuperConstructor.prototype is undefined');
48
        }
49
50
        /**
51
         * for convenience, `SuperConstructor` will be accessible through the
52
         * `Constructor.super_` property
53
         */
54 1
        Constructor.super_ = SuperConstructor;
55
56 1
        Constructor.prototype = Object.create(SuperConstructor.prototype);
57 1
        Constructor.prototype.constructor = Constructor;
58
    };
59
60
    /**
61
     * Turns an Array into an associative Object (while keeping reference!)
62
     *
63
     * @param {Array}                 arr    Array of Objects to turn into an
64
     *                                       associative Object
65
     * @param {String|Array|Function} mapBy  optional mapping key, can be a
66
     *                                       simple string (property name in
67
     *                                       the abjects of arr), a list of
68
     *                                       property names (which are
69
     *                                       combined) or a function which
70
     *                                       returns a unique id to use
71
     *
72
     * @throws {TypeError} if arr is not an Array or mapBy is set but not of
73
     *                     correct type (String, Array, Function)
74
     *
75
     * @returns {Object}
76
     */
77 1
    var toObject = function(arr, mapBy) {
78 7
        var obj = {};
79
80 7
        if (!Array.isArray(arr)) {
81 2
            throw new TypeError('arr argument is not of type Array');
82
        }
83
84 6
        if (mapBy !== undefined
85
            && typeof mapBy !== 'string'
86
            && !Array.isArray(mapBy)
87
            && typeof mapBy !== 'function'
88
        ) {
89 1
            throw new TypeError(
90
                'mapBy argument is not of type {String|Array|Function}'
91
            );
92
        }
93
94 4
        var methods = {
95
            string: function(val) {
96 3
                this.undefined(val, val[mapBy]);
97
            },
98
            object: function(val) {
99 3
                var newKey = mapBy.map(function(propertyName){
100 6
                    return val[propertyName];
101
                }).join('_');
102
103 3
                this.undefined(val, newKey);
104
            },
105
            function: function(val, i, arr) {
106 3
                this.undefined(val, mapBy(val, i, arr));
107
            },
108
            undefined: function(val, newKey) {
109 13
                if (typeof newKey === 'string'
110
                    || typeof newKey === 'number'
111
                ) {
112 13
                    obj[newKey] = val;
113
                }
114
            }
115
        };
116
117
        /**
118
         * run the designated method by mapBy type from the methods object
119
         * it binds the methods object so we can use the undefined setter method
120
         * for different mapBy types and don't have to maintain multiple but
121
         * same conditions
122
         */
123 4
        arr.forEach(
124
            methods[(typeof mapBy)].bind(methods)
125
        );
126
127 4
        return obj;
128
    };
129
130 1
    return {
131
        inherits: inherits,
132
        toObject: toObject
133
    };
134
}));
135