Passed
Pull Request — master (#106)
by Mark
02:38
created

Collection.toObject   A

Complexity

Conditions 4

Size

Total Lines 4
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 4
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
import * as Operators from './Collection/Where/Operators';
2
3
/**
4
 *
5
 */
6
export default class Collection extends Array {
7
8
    constructor(...items) {
9
        super(...items);
10
    }
11
12
    get operators() {
13
        return {
14
            '==': Operators.equal,
15
            '!=': Operators.notEqual,
16
            '>=': Operators.gtAndEqual,
17
            '<=': Operators.ltAndEqual,
18
            '>': Operators.gt,
19
            '<': Operators.lt,
20
        }
21
    }
22
23
    first() {
24
        return this[0] ?? null;
25
    }
26
27
    last() {
28
        return this.slice(-1)[0] ?? null;
29
    }
30
31
    merge(array): Collection {
32
        this.push(...array);
33
        return this;
34
    }
35
36
    pluck(field: string, keyField = '') {
37
        const lookUpFields = field.split('.');
38
39
        if (keyField) {
40
            const lookUpKeyField = keyField.split('.');
41
            const result = {};
42
            for (const i in this) {
43
                result[this._getRowFieldResult(this[i], lookUpKeyField)] = this._getRowFieldResult(this[i], lookUpFields);
44
            }
45
            return result;
46
        }
47
48
        const result = [];
49
        for (const i in this) {
50
            result.push(this._getRowFieldResult(this[i], lookUpFields));
51
        }
52
53
        return result;
54
    }
55
56
    random() {
57
        return this[Math.round(((this.length - 1) * Math.random()))];
58
    }
59
60
    unique(field: string): Collection {
61
        const unique = {};
62
        for (const i in this) {
63
            unique[this[i][field]] = this[i];
64
        }
65
66
        return new Collection(...Object.values(unique));
67
    }
68
69
    where(field: string, operator: string, value = null): Collection {
70
        value = value ?? operator;
71
        operator = (operator === value) ? '==' : operator;
72
73
        if (!Object.prototype.hasOwnProperty.call(this.operators, operator)) {
74
            throw new Error("Invalid comparison operator used");
75
        }
76
77
        return this.whereIfFunction(field, (field, object) => {
78
            return this.operators[operator](object[field], value);
79
        })
80
    }
81
82
    whereBetween(field: string, values): Collection {
83
        return this.whereIfFunction(field, (field, object) => {
84
            const fieldValue = object[field];
85
            return fieldValue >= values[0] && fieldValue <= values[1]
86
        });
87
    }
88
89
    whereIfFunction(field: string, whereIfFunction: CallableFunction): Collection {
90
        const register = new Collection();
91
        for (const i in this) {
92
            if (whereIfFunction(field, this[i])) {
93
                register.push(this[i]);
94
            }
95
        }
96
        return register;
97
    }
98
99
    whereIn(field: string, values): Collection {
100
        return this.whereIfFunction(field, (field, object) => {
101
            return values.includes(object[field]);
102
        });
103
    }
104
105
    whereInstanceOf(classInstance): Collection {
106
        return this.whereIfFunction(null, (field, object) => {
107
            return object instanceof classInstance;
108
        });
109
    }
110
111
    whereNotBetween(field: string, values): Collection {
112
        return this.whereIfFunction(field, (field, object) => {
113
            const fieldValue = object[field];
114
            return !(fieldValue >= values[0] && fieldValue <= values[1])
115
        });
116
    }
117
118
    whereNotIn(field: string, values): Collection {
119
        return this.whereIfFunction(field, (field, object) => {
120
            return !values.includes(object[field]);
121
        });
122
    }
123
124
    whereNotInstanceOf(classInstance): Collection {
125
        return this.whereIfFunction(null, (field, object) => {
126
            return !(object instanceof classInstance);
127
        });
128
    }
129
130
    whereNotNull(field: string): Collection {
131
        return this.whereIfFunction(field, (field, object) => {
132
            return object[field] !== null;
133
        });
134
    }
135
136
    whereNull(field: string): Collection {
137
        return this.whereIfFunction(field, (field, object) => {
138
            return object[field] === null;
139
        });
140
    }
141
142
    toJSON() {
143
        return this.toObject();
144
    }
145
146
    toObject() {
147
       return this.map((item) => {
148
           return (item.toObject?.() ?? item);
149
       });
150
    }
151
152
    private _getRowFieldResult(row, lookUpFields) {
153
        let resultField = row[lookUpFields[0]] ?? null;
154
        for (let i = 1; i < lookUpFields.length; i++) {
155
            const currentField = lookUpFields[i];
156
157
            if (resultField === null) {
158
                break;
159
            }
160
161
            if (resultField instanceof Collection) {
162
                return resultField.pluck(lookUpFields[i]);
163
            }
164
165
            resultField = resultField[currentField] ?? null;
166
        }
167
168
        return resultField;
169
    }
170
}