Completed
Push — master ( d362a9...56faa4 )
by Mark
14s queued 11s
created

Collection._getRowFieldResult   B

Complexity

Conditions 8

Size

Total Lines 25
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 15
dl 0
loc 25
rs 7.3333
c 0
b 0
f 0
1
/**
2
 *
3
 */
4
export default class Collection extends Array {
5
6
    /**
7
     *
8
     * @param items
9
     */
10
    constructor(...items) {
11
        super(...items);
12
    }
13
14
    /**
15
     *
16
     * @param row
17
     * @param lookUpFields
18
     * @return {{}|[]|*}
19
     * @private
20
     */
21
    _getRowFieldResult(row, lookUpFields) {
22
        let resultField = row[lookUpFields[0]] ?? null;
23
        for (let i = 1; i < lookUpFields.length; i++) {
24
            const currentField = lookUpFields[i];
25
26
            if (resultField === null) {
27
                break;
28
            }
29
30
            if (resultField instanceof Collection) {
31
                return resultField.pluck(lookUpFields[i]);
32
            }
33
34
            resultField = resultField[currentField] ?? null;
35
        }
36
37
        return resultField;
38
    }
39
40
    /**
41
     *
42
     * @return {T|null}
43
     */
44
    first() {
45
        return this[0] ?? null;
46
    }
47
48
    /**
49
     * @return {string}
50
     */
51
    jsonStringify() {
52
        return JSON.stringify(this);
53
    }
54
55
    /**
56
     *
57
     * @return {T|null}
58
     */
59
    last() {
60
        return this.slice(-1)[0] ?? null;
61
    }
62
63
    /**
64
     *
65
     * @param array
66
     * @return {Collection}
67
     */
68
    merge(array) {
69
        this.push(...array);
70
        return this;
71
    }
72
73
    /**
74
     *
75
     * @param field
76
     * @param keyField
77
     * @return {{}|[]}
78
     */
79
    pluck(field, keyField = '') {
80
        const lookUpFields = field.split('.');
81
82
        if (keyField) {
83
            const lookUpKeyField = keyField.split('.');
84
            const result = {};
85
            for (const i in this) {
86
                result[this._getRowFieldResult(this[i], lookUpKeyField)] = this._getRowFieldResult(this[i], lookUpFields);
87
            }
88
            return result;
89
        }
90
91
        const result = [];
92
        for (const i in this) {
93
            result.push(this._getRowFieldResult(this[i], lookUpFields));
94
        }
95
96
        return result;
97
    }
98
99
    /**
100
     *
101
     * @return {T}
102
     */
103
    random() {
104
        return this[Math.round(((this.length - 1) * Math.random()))];
105
    }
106
107
    /**
108
     *
109
     * @param field
110
     * @return {Collection}
111
     */
112
    unique(field) {
113
        const unique = {};
114
        for (const i in this) {
115
            unique[this[i][field]] = this[i];
116
        }
117
118
        return new Collection(...Object.values(unique));
119
    }
120
121
    /**
122
     *
123
     * @param field
124
     * @param operator
125
     * @param value
126
     * @return {boolean|Collection}
127
     */
128
    where(field, operator, value) {
129
        value = value ?? operator;
130
        operator = (operator === value) ? '==' : operator;
131
        const operators = {
132
            '>'(fieldValue, value) {
133
                return fieldValue > value;
134
            },
135
            '>='(fieldValue, value) {
136
                return fieldValue >= value;
137
            },
138
            '<'(fieldValue, value) {
139
                return fieldValue < value;
140
            },
141
            '<='(fieldValue, value) {
142
                return fieldValue <= value;
143
            },
144
            '!='(fieldValue, value) {
145
                return fieldValue != value;
146
            },
147
            '=='(fieldValue, value) {
148
                return fieldValue == value;
149
            }
150
        }
151
152
        if (!Object.prototype.hasOwnProperty.call(operators, operator)) {
153
            throw new Error("Invalid comparison operator used");
154
        }
155
156
        return this.whereIfFunction(field, (field, object) => {
157
            return operators[operator](object[field], value);
158
        })
159
    }
160
161
    /**
162
     *
163
     * @param field
164
     * @param values
165
     * @return {Collection}
166
     */
167
    whereBetween(field, values) {
168
        return this.whereIfFunction(field, (field, object) => {
169
            const fieldValue = object[field];
170
            return fieldValue >= values[0] && fieldValue <= values[1]
171
        });
172
    }
173
174
    /**
175
     *
176
     * @param field
177
     * @param whereIfFunction
178
     * @return {Collection}
179
     */
180
    whereIfFunction(field, whereIfFunction) {
181
        const reqister = new Collection();
182
        for (const i in this) {
183
            if (whereIfFunction(field, this[i])) {
184
                reqister.push(this[i]);
185
            }
186
        }
187
        return reqister;
188
    }
189
190
    /**
191
     *
192
     * @param field
193
     * @param values
194
     * @return {Collection}
195
     */
196
    whereIn(field, values) {
197
        return this.whereIfFunction(field, (field, object) => {
198
            return values.includes(object[field]);
199
        });
200
    }
201
202
    /**
203
     *
204
     * @param classInstance
205
     * @return {Collection}
206
     */
207
    whereInstanceOf(classInstance) {
208
        return this.whereIfFunction(null, (field, object) => {
209
            return object instanceof classInstance;
210
        });
211
    }
212
213
    /**
214
     *
215
     * @param field
216
     * @param values
217
     * @return {Collection}
218
     */
219
    whereNotBetween(field, values) {
220
        return this.whereIfFunction(field, (field, object) => {
221
            const fieldValue = object[field];
222
            return !(fieldValue >= values[0] && fieldValue <= values[1])
223
        });
224
    }
225
226
    /**
227
     *
228
     * @param field
229
     * @param values
230
     * @return {Collection}
231
     */
232
    whereNotIn(field, values) {
233
        return this.whereIfFunction(field, (field, object) => {
234
            return !values.includes(object[field]);
235
        });
236
    }
237
238
    /**
239
     *
240
     * @param classInstance
241
     * @return {Collection}
242
     */
243
    whereNotInstanceOf(classInstance) {
244
        return this.whereIfFunction(null, (field, object) => {
245
            return !(object instanceof classInstance);
246
        });
247
    }
248
249
    /**
250
     *
251
     * @param field
252
     * @return {Collection}
253
     */
254
    whereNotNull(field) {
255
        return this.whereIfFunction(field, (field, object) => {
256
            return object[field] !== null;
257
        });
258
    }
259
260
    /**
261
     *
262
     * @param field
263
     * @return {Collection}
264
     */
265
    whereNull(field) {
266
        return this.whereIfFunction(field, (field, object) => {
267
            return object[field] === null;
268
        });
269
    }
270
}