JavaScript30 https://javascript30.com/ 为 Wes Bos 推出的一项为期 30 天的挑战, 旨在帮助人们用纯 JavaScript 来实现效果, 初学者若想在 JS 方面快速精进, 不妨一试. 现在你看到的是该系列总结的第一篇, 不知何时能做完 30 题, 就不在此信誓旦旦立 flag 了. 本题为第四题.
实现效果
本章节是为介绍 JS Array 的几个常用方法, 包含 filter(),map(),sort(),reduce(), 并在 Console 面板中查看结果. 其中文档已给出两组数组:
第一组: inventors 数组, 包含名, 姓, 出生日期以及死亡日期
- const inventors = [
- { first: 'Albert', last: 'Einstein', year: 1879, passed: 1955 },
- ......
- { first: 'Hanna', last: 'Hammarström', year: 1829, passed: 1909 }
- ];
第二组: people 数组, 包含一组人名, 名姓之间用逗号分隔.
const people = ['Beck, Glenn', ...... , 'Blake, William'];
题目如下:
筛选出生于 16 世纪的发明家;
以数组形式, 列出其名与姓;
根据其出生日期, 并从大到小排序;
计算所有的发明家加起来一共活了几岁;
按照其年龄大小排序;
利用给出的网站 (https://en.wikipedia.org/wiki/Category:Boulevards_in_Paris), 列出包含'de'字节的巴黎大道;
按照姓氏排序;
统计出数组中每个种类的数量.
知识点
filter() https://developer.mozilla.org/zh-CN/docs/web/JavaScript/Reference/Global_Objects/Array/filter
过滤操作, 筛选符合条件的所有元素, 若为 true 则返回组成新数组, 以第一题为例:
- function bornyear(inventor) {
- return inventor.year>= 1500 && inventor.year <1600;
- }
- var fifteen = inventors.filter(bornyear);
- console.table(fifteen);
- // 可简化为
- const fifteen = inventors.filter(inventor => (inventor.year>= 1500 && inventor.year <1600));
- map() https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/map
映射操作, 对原数组每个元素进行处理, 并回传新的数组. 以第二题为例:
- const fullnames = inventors.map(inventor => `${inventor.first} ${inventor.last}`);
- console.table(fullnames);
- sort() https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
排序操作, 默认排序顺序是根据字符串 Unicode 码点, 如 10 在 2 之前, 而数字又在大写字母之前, 大写字母在小写字母之前. 也可使用比较函数, 数组会按照调用该函数的返回值排序, 格式如下:
- function compare(a, b) {
- if (a <b) {
- // 按某种排序标准进行比较, a 小于 b
- return -1;
- }
- if (a> b) {
- return 1;
- }
- // a must be equal to b
- return 0;
- }
要比较数字而非字符串, 比较函数可以简单的以 a 减 b, 如下的函数将会将数组升序排列:
- function compareNumbers(a, b) {
- return a - b;
- }
针对第三题, 我们就可以简单用加减比较:
- const birthdate = inventors.sort((inventora, inventorb) => (inventorb.year - inventora.year));
- console.table(birthdate)
而第七题, 则需要按返回值比较:
- const sortName = inventors.sort((a, b) => {
- return (a.last> b.last) ? 1 : -1;
- })
- console.table(sortName);
- reduce()
归并操作, 总共两个参数, 第一个是函数, 可以理解为累加器, 遍历数组累加回传的返回值, 第二个是初始数值. 如果没有提供初始值, 则将使用数组中的第一个元素. 以第四题为例:
- const totalyears = inventors.reduce((total, inventor) => { return total + (inventor.passed - inventor.year); }, 0);
- console.log(totalyears);
reduce() 方法讲同样用于第八题:
- const sumup = data.reduce(function (obj, item) {
- if (!obj[item]) {
- obj[item] = 0;
- }
- obj[item]++;
- return obj;
- }, {});
- console.log(sumup);
值得注意的是, 回调函数的第一个参数也可以为对象, 存储每一类物品的数量. 关于对象, 如需深入理解, 可参考阮一峰的博客 http://javascript.ruanyifeng.com/#oop .
map() 与 filter() 结合
参考第六题, 题目要求在该网站 https://en.wikipedia.org/wiki/Category:Boulevards_in_Paris 筛选出含有'de'字节的巴黎大道; 首选取得对应节点的元素, 并转化为数组, 再利用. includes() 方法就可以得到.
- const category = document.querySelector('.mw-category');
- const links = Array.from(category.querySelectorAll('a'));
- const de = links.map(link => link.textContent).filter(streetName => streetName.includes('de'));
- console.table(de)
来源: https://juejin.im/post/5ab4ab01f265da23793c17e0