Passed
Push — master ( b878e4...64f3a1 )
by Pieter Epeüs
26:11 queued 16:14
created

objects.js ➔ getKeys   A

Complexity

Conditions 4

Size

Total Lines 18
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 11
dl 0
loc 18
rs 9.85
c 0
b 0
f 0
cc 4
1
/**
2
 * Object helper
3
 */
4
module.exports = class Obj {
5
    /**
6
     * Set the original and prefix.
7
     *
8
     * @param {object} original
9
     * @param {string} prefix
10
     */
11
    constructor(original, prefix) {
12
        this.original = original;
13
        this.prefix = prefix;
14
        this.flatObject = {};
15
        this.parse();
16
    }
17
18
    /**
19
     * flatten the object 1 level per time.
20
     */
21
    parse() {
22
        Object.entries(this.original).forEach(
23
            ([originalRowIndex, originalRow]) => {
24
                let index = originalRowIndex;
25
26
                if (this.prefix) {
27
                    index = [this.prefix, originalRowIndex].join('.');
28
                }
29
30
                if (typeof originalRow === 'object') {
31
                    const childRows = new Obj(originalRow, index).flat;
32
33
                    this.flatObject = Object.assign(this.flatObject, childRows);
34
35
                    return;
36
                }
37
38
                this.flatObject[index] = originalRow;
39
            }
40
        );
41
    }
42
43
    /**
44
     * Get the flat object.
45
     *
46
     * @return {object}
47
     */
48
    get flat() {
49
        return this.flatObject;
50
    }
51
52
    /**
53
     * Get the object entries.
54
     *
55
     * @return {array}
56
     */
57
    entries() {
58
        return Object.entries(this.flatObject);
59
    }
60
61
    /**
62
     * Get the object keys.
63
     *
64
     * @return {array}
65
     */
66
    keys() {
67
        return Object.keys(this.flatObject);
68
    }
69
70
    /**
71
     * Get the object values.
72
     *
73
     * @return {array}
74
     */
75
    values() {
76
        return Object.values(this.flatObject);
77
    }
78
79
    /**
80
     * Get the object length.
81
     *
82
     * @return {number}
83
     */
84
    get length() {
85
        return Object.keys(this.flatObject).length;
86
    }
87
88
    /**
89
     * Get an item by key.
90
     *
91
     * @param {string} key
92
     * @param {object|null} defaultValue
93
     *
94
     * @return {object|null}
95
     */
96
    getByKey(key, defaultValue) {
97
        if (this.originalHas(key)) {
98
            return Object.getOwnPropertyDescriptor(this.original, key).value;
99
        }
100
101
        if (this.has(key)) {
102
            return this.flatObject[key];
103
        }
104
105
        if (this.includes(key)) {
106
            return this.entries()
107
                .filter(([currentKey]) => currentKey.startsWith(key))
108
                .reduce((accumulator, [currentKey, currentValue]) => {
109
                    const subKey = currentKey.substring(key.length + 1);
110
                    accumulator[subKey] = currentValue;
111
                    return accumulator;
112
                }, {});
113
        }
114
115
        return defaultValue;
116
    }
117
118
    /**
119
     * Get keys of an item.
120
     *
121
     * @param {array} keys
122
     * @param {object|null} defaultValue
123
     *
124
     * @return {object|null}
125
     */
126
    getFlatKeys(keys, defaultValue) {
127
        const result = this.entries().filter(([currentKey]) =>
128
            keys.some(key => currentKey.startsWith(key))
129
        );
130
131
        if (result.length < 1) {
132
            return defaultValue;
133
        }
134
135
        return Object.fromEntries(result);
136
    }
137
138
    /**
139
     * Get keys of an item.
140
     *
141
     * @param {array} keys
142
     * @param {object|null} defaultValue
143
     *
144
     * @return {object|null}
145
     */
146
    getKeys(keys, defaultValue) {
147
        const result = keys.reduce((accumulator, currentKey) => {
148
            const key = currentKey.toString();
149
            const value = this.getByKey(key);
150
151
            if (value) {
152
                accumulator[key] = value;
153
            }
154
155
            return accumulator;
156
        }, {});
157
158
        if (Object.keys(result).length < 1) {
159
            return defaultValue;
160
        }
161
162
        return result;
163
    }
164
165
    /**
166
     * Check if the original object has a key.
167
     *
168
     * @param {string} key
169
     *
170
     * @return {boolean}
171
     */
172
    originalHas(key) {
173
        return Object.prototype.hasOwnProperty.call(this.original, key);
174
    }
175
176
    /**
177
     * Check if the object has a key.
178
     *
179
     * @param {string} key
180
     *
181
     * @return {boolean}
182
     */
183
    has(key) {
184
        return Object.prototype.hasOwnProperty.call(this.flatObject, key);
185
    }
186
187
    /**
188
     * Check if the object has a key that includes.
189
     *
190
     * @param {string} key
191
     *
192
     * @return {boolean}
193
     */
194
    includes(key) {
195
        return this.keys().filter(item => item.startsWith(key)).length > 0;
196
    }
197
};
198