如何將不規則 Object 轉成 Array ?
栏目: JavaScript · 发布时间: 5年前
内容简介:對於可有可無資料,後端 API 可能回傳 Object,其 Property 可能不存在,但對於前端而言,我們想要的是 Array 方便 HTML template 做VS Code 1.35.1Quokka 1.0.227
對於可有可無資料,後端 API 可能回傳 Object,其 Property 可能不存在,但對於前端而言,我們想要的是 Array 方便 HTML template 做 v-for
,本文由實際 API 回傳資料所改寫,接近實務上應用。
Version
VS Code 1.35.1
Quokka 1.0.227
Ramda 0.26.1
Imperative
let lut = { price: 'General Price', price1: 'Shipping Price', price2: 'Duty-free price' }; let data = { title: 'FP in JavaScript', price: 100, prices: [ { price1: 120, price2: 80 } ] }; // fn :: {a} -> {b} -> [{c}] let fn = lut => obj => { let result = []; for(let x in obj) { if (x === 'price') { for(let z in lut) { if (x === z) { result.push({ title: lut[z], price: obj[x] }); } } } if (x === 'prices') { for(let y in obj.prices[0]) { for(let z in lut) { if (y === z) { result.push({ title: lut[z], price: obj.prices[0][y] }); } } } } } return result; }; console.dir(fn(lut)(data));
第 7 行
let data = { title: 'FP in JavaScript', price: 100, prices: [ { price1: 120, price2: 80 } ] };
實際 data
為 object,不是 array,注意其 price
並不規則,主要 price
在第一層,其餘在 prices
下。
第 1 行
let lut = { price: 'General Price', price1: 'Shipping Price', price2: 'Duty-free price' };
至於 price
、 price1
與 price2
所對應的意義,定義在 lut
object。
[ { title: 'General Price', price: 100 }, { title: 'Shipping Price', price: 120 }, { title: 'Duty-free price', price: 80 } ]
我們希望結果為 array,其 element 為 object,且根據 lut
顯示對應的 title
與 price
。
18 行
// fn :: {a} -> {b} -> [{c}] let fn = lut => obj => { let result = []; for(let x in obj) { if (x === 'price') { for(let z in lut) { if (x === z) { result.push({ title: lut[z], price: obj[x] }); } } } if (x === 'prices') { for(let y in obj.prices[0]) { for(let z in lut) { if (y === z) { result.push({ title: lut[z], price: obj.prices[0][y] }); } } } } } return result; };
由於結果為 array,imperative 會先建立 result
array,使用 for in
loop 讀取 property,再加上各種 if
判斷,建立 object 然後 push 進 result
array。
我們發現 imperative 作法雖然能求得結果,但程式碼可讀性非常差。
Functional
import { pipe, keys, filter, __, has, map } from 'ramda'; let lut = { price: 'General Price', price1: 'Shipping Price', price2: 'Duty-free price' }; let data = { title: 'FP in JavaScript', price: 100, prices: [ { price1: 120, price2: 80 } ] }; // pickAllPrice :: {a} -> {b} let pickAllPrice = obj => ({ ...obj, ...obj.prices[0] }); // objToArr :: {a} -> {b} -> [{c}] let objToArr = lut => obj => pipe( keys, filter(x => has(x, obj)), map(x => ({ title: lut[x], price: obj[x]})) )(lut); // fn :: {a} -> {b} -> [{c}] let fn = lut => obj => pipe( pickAllPrice, objToArr(lut), )(obj); console.dir(fn(lut)(data));
以 Functional 角度思考:
price
20 行
// pickAllPrice :: {a} -> {b} let pickAllPrice = obj => ({ ...obj, ...obj.prices[0] });
pickAllPrice()
將所有 prices
下的 property 全部整理到 object 第一層 property
27 行
// objToArr :: {a} -> {b} -> [{c}] let objToArr = lut => obj => pipe( keys, filter(x => has(x, obj)), map(x => ({ title: lut[x], price: obj[x]})) )(lut);
要將 object 轉成 array, keys()
是關鍵 function,它將 object 中所有的 key 轉成 array。
但 prices
下的 property 個數並不確定,可能只有 price1
而沒有 price2
,因此搭配 filter()
與 has()
,只過濾出 prices
下實際有的 property。
最後使用 map()
整理出我們要的格式。
33 行
// fn :: {a} -> {b} -> [{c}] let fn = lut => obj => pipe( pickAllPrice, objToArr(lut), )(obj);
將問題各個擊破後,最後由 fn()
將所有 function 整合起來。
Point-free
import { pipe, keys, filter, __, has, map, applySpec, prop } from 'ramda'; let lut = { price: 'General Price', price1: 'Shipping Price', price2: 'Duty-free price' }; let data = { title: 'FP in JavaScript', price: 100, prices: [ { price1: 120, price2: 80 } ] }; // pickAllPrice :: {a} -> {b} let pickAllPrice = obj => ({ ...obj, ...obj.prices[0] }); // objToArr :: {a} -> {b} -> [{c}] let objToArr = lut => obj => pipe( keys, filter(has(__, obj)), map(applySpec({ title: prop(__, lut), price: prop(__, obj) })) )(lut); // fn :: {a} -> {b} -> [{c}] let fn = lut => obj => pipe( pickAllPrice, objToArr(lut), )(obj); console.dir(fn(lut)(data));
filter()
與 map()
的 callback 可再進一步 point-free。
29 行
filter(has(__, obj)),
別忘了 has()
的 currying 特性,可以 has()
直接產生 filter()
所需的 callback。
30 行
map(applySpec({ title: prop(__, lut), price: prop(__, obj) }))
map()
的 callback 也能再使用 applySpec()
使其 point-free。
Conclusion
- Funtional 善於將問題最小化切割,然後各自擊破,最後再以 pipeline 加以整合,而不是如 imperative 一開始就思考如何整體解決問題
- Point-free 可視自身能力與程式碼可讀性取捨,不需強求
以上所述就是小编给大家介绍的《如何將不規則 Object 轉成 Array ?》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
乔布斯离开了,马斯克来了
[日]竹内一正 / 干太阳 / 中信出版社 / 2015-11
在电动汽车的创新上,特斯拉抓住了一个群体的独特需求,外形很酷,不烧油,智能化控制。所有的颠覆式创新都不是敲锣打鼓来的,而是隐藏在一片噪声里,马斯克给我们带来的特斯拉虽然不尽完美,但他做产品的思维和执着于未来的勇气,值得学习。埃隆•马斯克创办公司也不是为了赚钱,而是为了拯救人类和地球,电动汽车、太阳能发电、宇宙火箭,不管是哪一项都足以令一个国家付出巨大的代价去研究开发,但埃隆•马斯克却一个人在做这些......一起来看看 《乔布斯离开了,马斯克来了》 这本书的介绍吧!