[].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并没有人呼吁为此立标准,看来需求也不是很大,只是个人觉得这样写比较方便而已。
【小游戏】
你能证明自己不是上帝吗?
假如你是上帝,一日想玩一场体验人生的游戏。你设置一个程序,让自己在未来某个时间点开始的主观视角变成一个刚出生的婴儿,为了真实体验,你将暂时清除自己是上帝的记忆,这意味着游戏一旦开始,你将无法意识到自己是上帝,所以即使游戏很无聊也无法主动停止游戏。直到人体意外死亡或者自然死亡后游戏才结束,恢复上帝意识。
那么问题来了,抛开上面的假设,你如何证明现在的每一天不是处于游戏人生状态呢?答案就是,无法证明!