实现一个query方法-实现对数据的链式查询和处理

# 实现一个query方法-实现对数据的链式查询和处理

类似于 lazyman 题目来源:很久之前的群聊提问

目标: 实现一个 query 方法,实现对数据的链式查询和处理

function query(data) {}
1

要求

  1. query传入参数为原始数据(数组格式,每个元素都是对象)
  2. 通过进行链式调用对数据执行操作,支持的方法有 2.1 where(predicate) 根据参数的条件进行筛选,参数与 [].filter 的参数类似 2.2 orderBy(key, desc) :根据key的值进行排列,默认升序排列,当第二个参数为true时降序排列 2.3 groupBy(key):根据key 的值对数据元素进行分组,合并为二维数组 2.4 execute():执行所有处理并返回最终结果
  3. 执行execute方法时才真正执行操作并返回结果

测试用例

const data = [
  { name: 'foo', age: 16, city: 'shanghai' },
  { name: 'bar', age: 24, city: 'hangzhou' },
  { name: 'fiz', age: 22, city: 'shanghai' },
  { name: 'baz', age: 19, city: 'hangzhou' },
];

const query = (data) => {
  // TODO:
};

var res = query(data)
  .where((item) => item.age > 18)
  .orderBy('age')
  .groupBy('city')
  .execute();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

结果

[
    [
        {
            "name": "baz",
            "age": 19,
            "city": "hangzhou"
        },
        {
            "name": "bar",
            "age": 24,
            "city": "hangzhou"
        }
    ],
    [
        {
            "name": "fiz",
            "age": 22,
            "city": "shanghai"
        }
    ]
]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function query(data) {
 this.data = data
}

query.prototype.where = function (callback) {
 let res = [];
 data.forEach((item) => {
  if (callback(item)) {
   res.push(item)
  }
 });
 this.data = res;
 return this;
}

query.prototype.orderBy = function (key) {
 this.data.sort((a, b) => a[key] - b[key]);
 return this;
}

query.prototype.groupBy = function (key) {
  let map = new Map();
  this.data.forEach((cur) => {
    if (map.has(cur[key])) {
      map.set(cur[key], [...map.get(cur[key]), cur]);
    } else {
      map.set(cur[key], [cur]);
    }
  });
  this.data = [...map.values()];
  return this;
};

query.prototype.execute = function () {
  return this.data;
};
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
上次更新: 2022/7/29 上午11:39:16