有限集合的创建、映射及过滤 有限集合

有限集合

数学中,一个集合被称为有限集合,简单来说就是元素个数有限 ————《维基百科》

通过上面这句话,我们可以清楚的知道,一个有限集合可以通过穷举法将集合里面的数一一例举出来,这是一条非常重要的原则。在 JavaScript 的世界里,类数组(ArrayLike)、数组(Array)和普通对象(Object)可以看作为有限集合,于是乎,我们可以对它们进行创建、映射及过滤操作。

本篇博客内容在整体上以抽象现象直击本质,定有不严谨的地方。不过重在学习思想

创建

我定义的创建,对有限集合的创建、或向其中添加数据,是”多”的操作。

我认为我们声明一个数组、对象变量或为对象添加属性均属于创建操作的范畴。

1
2
3
4
5
6
7
8
9
10
11
12
js复制代码// 数组
const subjects = [];

// 通过数组的 push 方法向 subjects 数组添加元素
subjects.push("math");
console.log(subjects); // ["math"]

// 对象
const blog = {};

blog.title = "有限集合的添加、映射及过滤";
console.log(blog); // { title: "有限集合的创建、映射及过滤" }

下面我们使用 for 循环实现数组的 push 方法。

1
2
3
4
5
6
7
8
9
10
11
12
js复制代码const myPush = (obj, ...args) => {
let len = obj.length,
argsLen = args.length;

for (let i = 0; i < argsLen; i += 1) {
obj[len + i] = args[i];
}

return obj;
};

console.log(myPush([], "1", "2")); // [1, 2]

映射

我定义的映射,改造有限集合中的元素,但元素的总数保持不变,是“变”的操作。

数组的 map 方法。map() 方法创建一个新数组,其结果是该数组中的每个元素都调用一次提供的函数后的返回值。

1
2
3
4
js复制代码// 语法
var new_array = arr.map(function callback(currentValue[, index[, array]]) {
// Return element for new_array
}[, thisArg])

我们来看看数组的 map 方法在下面这个例子中的使用。

1
2
3
4
5
6
js复制代码const numbers = [1, 4, 9, 16];

// pass a function to map
const result = numbers.map((x) => x * 2);

console.log(result); // [2, 8, 18, 32]

再来看下对象的 keys 方法。Object.keys() 方法会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和使用 for…in 循环遍历该对象时返回的顺序一致 。

1
2
js复制代码// 语法
Object.keys(obj);

接下来看看 keys 方法的实际使用。

1
2
3
4
5
6
js复制代码const book = {
title: "高级",
price: 99,
};

console.log(Object.keys(book)); // ['title', 'price']

虽然经过 Object.keys 方法处理后,返回结果的类型是数组,且值为对象的属性,但元素的个数没变,由原来的键值对变为键,这是仍属于改造的过程。

过滤

我定义的映射,包含删除有限集合中的某些或某个元素、是”少”的操作。

我们先来看看数组的 filter 的方法。

1
2
js复制代码// 语法
var newArray = arr.filter(callback(element[, index[, array]])[, thisArg]);

从一组数找出大于 9 的数,请看下面的例子。

1
2
3
4
5
js复制代码const numbers = [12, 23, 56, 78, 1, 6];

const result = numbers.filter((num) => num > 9);

console.log(result); // [12, 23,56,78];

filter 方法会过滤出符合判定条件的元素,用新数组的形式返回结果。元素的数量减少,

接着,我们来实现过滤对象属性的 filterObj 方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
js复制代码const blog = {
title: "有限集合的添加、映射及过滤",
author: "qinghuanI",
};

const filterObj = function (obj, key) {
return Object.entries(obj)
.filter((item) => item[0] !== key)
.reduce((prev, cur) => {
prev[cur[0]] = cur[1];
return prev;
}, {});
};

console.log(filterObj(blog, "title")); // { author: "qinghuanI" }

基石之 for 循环

经过创建、映射和过滤三部分的讲解,我们可以看出,push、map、filter、filterObj 等方法的实现中都使用了 for 循环。

由此可以总结,for 循环控制语句是实现有限集合操作的基石。

Underscore、Lodash 与 Ramda 比较

Underscore 是一个 JavaScript 实用库,提供了一整套函数式编程的实用功能,但是没有扩展任何 JavaScript 内置对象。

Lodash 是一个一致性、模块化、高性能的 JavaScript 实用工具库。Lodash 消除了处理数组,数字,对象,字符串等的麻烦,使处理数据变得更容易。相比 Underscore,Lodash 支持模块化使用。

Ramda 是一款实用的 JavaScript 函数式编程库。侧重函数式使用风格。

下表是三个库之间的对比

名称 类型 模块化 函数式
Underscore Collection、Array、Function、Object、Util
Lodash Array、Collection、Date、Function、Lang、Math、Number、Object、Seq、String、Util、Properties、Methods
Ramda List、Function、Logic、Object、Relation、Math、String

Lodash 可以处理更多类型的数据、并且支持模块化,推荐在实际的项目中使用 Lodash。

总结

那么对有限集合的操作就是”多、变、少”这三个哲学

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%