[].filter是一个非常实用的MapReduce方法,用于过滤掉列表中不需要的元素,返回一个新列表,所以是纯函数。

Array.prototype.filter

filter() 方法创建一个新数组, 其包含通过所提供函数实现的测试的所有元素。 

语法

var newArray = arr.filter(callback(element[, index[, array]])[, thisArg])

参数

callback:用来测试数组的每个元素的函数。返回 true 表示该元素通过测试,保留该元素,false 则不保留。它接受以下三个参数:

  element:数组中当前正在处理的元素。

  index可选:正在处理的元素在数组中的索引。

  array可选:调用了 filter 的数组本身。

thisArg可选:执行 callback 时,用于 this 的值。

返回值

一个新的、由通过测试的元素组成的数组,如果没有任何数组元素通过测试,则返回空数组。

但是列表和字典类型是可以互换的,因为字典中的键值对(key,value)就完美对应着列表中的index和element,json的这2种复合类型都来自高等代数中的张量。可遗憾的是js对象的原型链上并没有filter,可能是因为Array也属于对象而产生歧义了。

不过既然列表和字典的结构可以一一映射,我们就可以依据Array.prototype.filter来构造Object.prototype.filter,这里的Object应该是纯字典类型。

结果

Object.defineProperty(Object.prototype, 'filter', {
        enumerable: false,
        writable:true,
        value: function (check = ((v, k, o) => undefined), this4check = undefined) {
            const oldObj = this;
            const newObj = {};
            Object.entries(oldObj).forEach(([key, value]) => {
                if (check.bind(this4check)(value, key, oldObj))
                    newObj[key] = value;
            })
            return newObj;
        },
    });

无论是浏览器环境还是node环境下都好用。

实例

const 成绩单={姓名:'Jim',语言学:88,数学:59,其他:'B'}
成绩单.filter((v,k)=>['姓名','数学'].includes(k));
    >{姓名: "Jim", 数学: 59}

不过Google了一下,Object.prototype.filter并没有人呼吁为此立标准,看来需求也不是很大,只是个人觉得这样写比较方便而已。


 

【小游戏】

你能证明自己不是上帝吗?

假如你是上帝,一日想玩一场体验人生的游戏。你设置一个程序,让自己在未来某个时间点开始的主观视角变成一个刚出生的婴儿,为了真实体验,你将暂时清除自己是上帝的记忆,这意味着游戏一旦开始,你将无法意识到自己是上帝,所以即使游戏很无聊也无法主动停止游戏。直到人体意外死亡或者自然死亡后游戏才结束,恢复上帝意识。

那么问题来了,抛开上面的假设,你如何证明现在的每一天不是处于游戏人生状态呢?答案就是,无法证明!