function groupBy(array, key) {
const groups = array.reduce((result, current) => {
if (Object.prototype.hasOwnProperty.call(current, key)) {
if (result[current[key]]) {
result[current[key]] = [...result[current[key]], current];
} else {
result[current[key]] = [current];
}
}
return result;
}, {});
return Object.values(groups);
}
function Query(data) {
this.data = data;
this.queue = [];
this.compose = function (fn) {
this.queue.push(fn);
return this;
};
}
Query.prototype = {
where: function (predicate) {
return this.compose(function () {
this.data = this.data.filter(predicate);
});
},
orderBy: function (key, desc) {
return this.compose(function () {
this.data = this.data.sort((current, next) =>
desc ? next[key] - current[key] : current[key] - next[key]
);
});
},
groupBy: function (key) {
return this.compose(function () {
this.data = groupBy(this.data, key);
});
},
execute: function () {
this.queue.forEach((fn) => fn.apply(this));
return this.data;
},
};
function query(data) {
if (!Array.isArray(data)) {
throw new TypeError(`${data} is not a array`);
}
return new Query(data);
}
const testData = [
{ name: "foo", age: 16, city: "shanghai" },
{ name: "bar", age: 24, city: "hangzhou" },
{ name: "fiz", age: 22, city: "shanghai" },
{ name: "baz", age: 19, city: "hangzhou" },
];
console.log(
query({})
.where((item) => item.age > 15)
.orderBy("age", true)
.groupBy("city")
.execute()
);