forked from urfu-2015/javascript-tasks-3
-
Notifications
You must be signed in to change notification settings - Fork 0
/
lego.js
126 lines (111 loc) · 4.02 KB
/
lego.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
'use strict';
// Метод, который будет выполнять операции над коллекцией один за другим
module.exports.query = function (collection) {
for (var i = 1; i < arguments.length; i++) {
var action = arguments[i];
var actionName = action[0];
var actionFun = action[1];
switch (actionName) {
// функции типа coll обрабатывают всю коллекцию
case 'coll':
collection = actionFun(collection);
break;
// функции типа filter проверяют запись на соответствие условию
case 'filter':
collection = collection.filter(actionFun);
break;
// функции типа transform трансформируют запись
case 'transform':
collection = collection.map(actionFun);
break;
}
}
return collection;
};
// Оператор reverse, который переворачивает коллекцию
module.exports.reverse = function () {
return ['coll', function (collection) {
var changedCollection = collection.reverse();
// Возращаем изменённую коллекцию
return changedCollection;
}];
};
// Оператор limit, который выбирает первые N записей
module.exports.limit = function (n) {
return ['coll', function (collection) {
if (n >= 0) {
return collection.slice(0, n);
} else {
throw new RangeError('Parameter must be between 0 and ' + collection.length);
}
}];
};
// Вам необходимо реализовать остальные операторы:
// select, filterIn, filterEqual, sortBy, format, limit
module.exports.select = function () {
var selectedFields = [].slice.call(arguments);
return ['transform', function (record) {
return selectedFields.reduce(function (result, field) {
if (field in record) {
result[field] = record[field];
}
return result;
}, {});
}];
};
module.exports.filterIn = function (field, values) {
return ['filter', function (record) {
return values.some(function (value) {
return value === record[field];
});
}];
};
module.exports.filterEqual = function (field, value) {
return ['filter', function (record) {
return value === record[field];
}];
};
module.exports.sortBy = function (field, type) {
return ['coll', function (collection) {
var sortValue = {asc: 1, desc: -1}[type] || 1;
return collection.sort(function (record1, record2) {
if (record1[field] === record2[field]) {
return 0;
} else if (record1[field] > record2[field]) {
return sortValue;
} else {
return -sortValue;
}
});
}];
};
module.exports.format = function (field, func) {
return ['transform', function (record) {
record[field] = func(record[field]);
return record;
}];
};
// Будет круто, если реализуете операторы:
// or и and
module.exports.or = function () {
var actions = [].slice.call(arguments);
return logicalAction(function (result, value) {
return result || value;
}, false, actions);
};
module.exports.and = function () {
var actions = [].slice.call(arguments);
return logicalAction(function (result, value) {
return result && value;
}, true, actions);
};
var logicalAction = function (reduceFun, reduceInit, actions) {
return ['filter', function (record) {
return actions.map(function (action) {
if (action[0] !== 'filter') {
throw new Error('Logical action accepts only filter actions');
}
return action[1](record);
}).reduce(reduceFun, reduceInit);
}];
};