使用 prop() 取得 Object 的 Property


2019-09-14


map() 的 Callback 常需要常需要從 Object 取得 Property,可使用 Ramda 的 prop() 使 Callback 能 Point-free。

Version

macOS Mojave 10.14.6
VS Code 1.38.1
Quokka 1.0.244
Ramda 0.26.1

Imperative

let data = [1, 2, 3];

let lut = {
  1: 'FP in JavaScript',
  2: 'RxJS in Action',
  3: 'Speaking JavaScript',
};

let fn = arr => {
  let result = [];

  for(let x of arr)
    result.push(lut[x]);

  return result;
};

fn(data);

一個實務上常見的需求,由 API 所得到的資料只有 代碼,而我們需要根據 代碼 轉成 對應資料 顯示。

至於 代碼顯示文字 的對照表,會存在 lut 內。

Imperative 會使用 for loop,若在 lut 比對到,則 push() 到新的 result array,最後回傳 result array。

Array.prototype.map()

let data = [1, 2, 3];

let lut = {
  1: 'FP in JavaScript',
  2: 'RxJS in Action',
  3: 'Speaking JavaScript',
};

let fn = arr => arr.map(x => lut[x]);

fn(data);

Array.prototype 有自帶 map(),所以我們也可以直接使用,再透過 lut[x] 加以對照轉換。

這種寫法已經比 Imperative 精簡很多,但仍有兩個問題:

  1. 由於內建的 map() 不是 curry function,因此 fn() 仍然要提供 arr argument,無法如 point-Free 那樣精簡
  2. x => lut[x] 這種 callback,是否有 point-free 寫法呢 ?

map()

import { map } from 'ramda';

let data = [1, 2, 3];

let lut = {
  1: 'FP in JavaScript',
  2: 'RxJS in Action',
  3: 'Speaking JavaScript',
};

let fn = map(x => lut[x]);

fn(data);

Ramda 亦提供 map(),與 Array.prototype.map() 不同在於他是個 curry function,最後一個參數為 data,因此 fn() 可以使用 point-free 寫法,程式碼更精簡。

map()
(a -> b) -> a -> b
將 a 格式資料轉換成 b 格式資料,且筆數不變

(a -> b)map() 要轉換的 callback

[a]:data 為 array

[b]:回傳為新的 array

由於最後一個 argument 為 data,使得 map() 可使用 point-free。

prop()

import { map, prop, __ } from 'ramda';

let data = [1, 2, 3];

let lut = {
  1: 'FP in JavaScript',
  2: 'RxJS in Action',
  3: 'Speaking JavaScript',
};

let fn = map(
  prop(__, lut)
);

fn(data);

不過之前的寫法,map() 的 callback 仍然不是 point-free,Ramda 特別提供了 prop(),專門產生這類 callback。

Ramda 的 function 最後一個 argument 都是 data,因此可以很簡單的省略 data 做 point-free,但本文需求有些特別,map() 傳進來的資料並不是 prop() 最後一個 argument,而是第一個 argument。

對於這種特殊需求,Ramda 另外提供 __ function 做 placeholder,專門負責傳入 data。

prop()
s -> {s: a} -> a | undefined
傳入 key 與 object,傳回 value

s:object 的 key

{s: a}:data 為 object

a | undefined:傳回 value,若找不到為 undefined

flip()

import { map, prop, flip } from 'ramda';

let data = [1, 2, 3];

let lut = {
  1: 'FP in JavaScript',
  2: 'RxJS in Action',
  3: 'Speaking JavaScript',
};

let fn = map(
  flip(prop)(lut)
);

fn(data);

若不想使用 __,也可以使用 flip(),將 prop() 的兩個 argument 順序調換,則可以使用 point-free。

flip()
((a, b, c, ...) -> z) -> (b -> a -> c -> ... -> z)
將 function 的前兩個 argument 順序調換,以配合 point-free

Conclusion

  • prop() 會傳回 Ramda 所需要的 callback,只要傳入 object 的 property 名稱即可
  • FP 的 data 都會放在最後一個 argument,因此可輕鬆做 point-free,但若剛好不是最後一個argument,可使用 __ 做 placeholder
  • 也可以使用 flip() 將 argument 順序調換

Reference

Ramda, map()
Ramda, prop()
Ramda, __
Ramda, flip()

  • 使用 pluck() 將 Array 中 Object 的指定 Property 取出

原文:大专栏  使用 prop() 取得 Object 的 Property

原文地址:https://www.cnblogs.com/chinatrump/p/11584742.html

时间: 2024-11-19 20:06:12

使用 prop() 取得 Object 的 Property的相关文章

[Angular 2] Using a Reducer to Change an Object's Property Inside an Array

Reducers are also often used for changing a single property inside of other reducers. This lesson shows how a type can enter the people reducer, but then the people reducer can use a different type to call the clock reducer and get a value back. So t

Object.create(): the New Way to Create Objects in JavaScript

There are a lot of ways to create Objects in JavaScript, perhaps even more to integrate inheritance into them. Just when you thought that you've seen every possible way to create JS objects, I'm here to announce that there's yet another: the new Obje

Object的新属性方法

ECMAScript5 Object的新属性方法 虽然说现在并不是所有的浏览器都已经支持ECMAScript5的新特性,但相比于ECMAScript4而言ECMAScript5被广大浏览器厂商广泛接受,目前主流的浏览器中只有低版本的IE不支持,其它都或多或少的支持了ECMAScript5的新特性,其中重中之重自然是一切对象的基类型--Object Object.create(prototype[,descriptors]) 这个方法用于创建一个对象,并把其prototype属性赋值为第一个参数,

ECMAScript5 Object的新属性方法

虽然说现在并不是所有的浏览器都已经支持ECMAScript5的新特性,但相比于ECMAScript4而言ECMAScript5被广大浏览器厂商广泛接受,目前主流的浏览器中只有低版本的IE不支持,其它都或多或少的支持了ECMAScript5的新特性,其中重中之重自然是一切对象的基类型——Object Object.create(prototype[,descriptors]) 这个方法用于创建一个对象,并把其prototype属性赋值为第一个参数,同时可以设置多个descriptors,关于dec

JS性能方面--内存管理及ECMAScript5 Object的新属性方法

Delete一个Object的属性会让此对象变慢(多耗费15倍的内存) var o = { x: 'y' }; delete o.x; //此时o会成一个慢对象 o.x; // var o = { x: 'y' }; o = null; //应该这样 闭包 在闭包中引入闭包外部的变量时,当闭包结束时此对象无法被垃圾回收(GC). var a = function() { var largeStr = new Array(1000000).join('x'); return function()

[转]ECMAScript5 Object的新属性方法

虽然说现在并不是所有的浏览器都已经支持ECMAScript5的新特性,但相比于ECMAScript4而言ECMAScript5被广大浏览器厂商广泛接受,目前主流的浏览器中只有低版本的IE不支持,其它都或多或少的支持了ECMAScript5的新特性,其中重中之重自然是一切对象的基类型——Object Object.create(prototype[,descriptors]) 这个方法用于创建一个对象,并把其prototype属性赋值为第一个参数,同时可以设置多个descriptors,关于dec

Object 构造函数的方法

Object.assign() (es6) 用于将所有可枚举属性的值从一个或多个源对象复制到目标对象.它将返回目标对象. Object.assign(target, ...sources) // target 目标对象. sources 源对象. 'use strict'; let obj1 = { a: 0 , b: { c: 0}}; let obj2 = Object.assign({}, obj1); console.log(JSON.stringify(obj2)); // { a:

JS_funciton,object,Array

今天学习了js数据类型的function,Object,Array 1.function是object的一种,也是一种数据类型--可以存储在变量.数组.对象中,也可以作为参数传递到方法中去,这是一个比较新的概念,也是与java,c#中的函数概念不一样的地方(以前只知道js中的function可以执行某个功能,接受参数.返回某个值,原来还可以当成数据值来传递,和number,string类型没两样!) function的两种定义方式: 1 //1 2 function test(msg) { 3

python 装饰器语法糖(@classmethod @staticmethod @property @name.)原理剖析和运用场景

引用:http://blog.csdn.net/slvher/article/details/42497781 这篇文章系统的介绍这几者之间的关系和区别.有兴趣的朋友可以到上面的链接查看原文,这里我把原文拷贝如下(如有侵权,通知马上删除) ==================================================================== 在阅读一些开源Python库的源码时,经常会看到在某个类的成员函数前,有类似于@staticmethod或@classme