如何將不規則 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 ?》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
零基础学Java Web开发
刘聪 编 / 机械工业出版社 / 2008-1 / 59.00元
《零基础学Java Web开发:JSP+Servlet+Sfruts+Spring+Hibernte》全面讲解Java Web应用开发的编程技术,并详细介绍Java Web开发中各种常用的技术,可作为Java Web开发技术的学习指南。 《零基础学Java Web开发:JSP+Servlet+Sfruts+Spring+Hibernte》共17章,分为3篇,其中第1~12章是基础篇,讲解了......一起来看看 《零基础学Java Web开发》 这本书的介绍吧!