# 一. 实现 maxBy 函数

  1. 描述:根据给定条件找到最大的数组项
  2. 类似 loadash如:
const data = [{ value: 6 }, { value: 2 }, { value: 4 }];

//=> { value: 6 }
maxBy(data, (x) => x.value);
1
2
3
4

面试追问:

如果最大的项有多个,则多个都返回,如下所示

const data = [{ value: 6 }, { value: 2 }, { value: 4 }, { value: 6 }];
//=> [{ value: 6 }, { value: 6 }]
maxBy(data, (x) => x.value);
1
2
3

# 二. 实现

**实现 1:**返回一项

const maxBy = (list, keyBy) =>
  list.reduce((x, y) => (keyBy(x) > keyBy(y) ? x : y));
1
2

**实现 2:**若需要返回多个项,则使用以下代码

const maxBy = (list, keyBy) => {
  return list.slice(1).reduce(
    (acc, x) => {
      if (keyBy(x) > keyBy(acc[0])) {
        return [x];
      }
      if (keyBy(x) === keyBy(acc[0])) {
        return [...acc, x];
      }
      return acc;
    },
    [list[0]]
  );
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 三. 相似题目

1如何找到当前页面出现次数最多的 HTML 标签

有三种 API 可以列出页面所有标签:

  • document.querySelector('*'),标准规范实现

  • $$('*'),devtools 实现

  • document.all,非标准规范实现

// 实现一个 maxBy 方便找出出现次数最多的 HTML 标签
const maxBy = (list, keyBy) =>
  list.reduce((x, y) => (keyBy(x) > keyBy(y) ? x : y));

function getFrequentTag() {
  const tags = [...document.querySelectorAll("*")]
    .map((x) => x.tagName)
    .reduce((o, tag) => {
      o[tag] = o[tag] ? o[tag] + 1 : 1;
      return o;
    }, {});
  return maxBy(Object.entries(tags), (tag) => tag[1]);
}
1
2
3
4
5
6
7
8
9
10
11
12
13

使用element.children递归迭代如下 (最终结果多一个 document)

function getAllTags(el = document) {
  const children = Array.from(el.children).reduce(
    (x, y) => [...x, ...getAllTags(y)],
    []
  );
  return children;
}
// 或者通过 flatMap 实现
function getAllTags(el = document) {
  const children = Array.prototype.flatMap.call(el.children, (x) =>
    getAllTags(x)
  );
  return [el, ...children];
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

2实现一个函数 max,找到数组中最大的一个值/两个值/N 个值