【发布时间】:2017-10-23 05:18:04
【问题描述】:
我正在尝试使用 Google Places API 来获取我所在位置的地名。
返回的数据结构有以下几种:
descriptor1: 'street number' | 'neighborhood' | 'postcode' | 'route' | 'locality' | 'postal_town' | 'administrative_area_level_2' | 'administrative_area_level_1' | 'country'
places: [
{
address_components: [{
long_name: 'string',
short_name: 'string',
types: {
0: descriptor1,
1?: descriptor2
}
}],
other_fields not relevant here
}
]
无法保证任何给定地点将有多少地址组件,或者是否有任何地址组件。无法保证哪些类型会被表示,哪些不会被表示。
我想编写代码,返回第一个地址组件的长名称,该组件具有'neighborhood' 的字段R.get(R.lensPath('types', '0')),如果存在locality,则返回postal_town,administrative_area_level_2,然后是administrative_area_level_1 和然后country。
所以我从R.pluck('address_components', places) 开始。现在我可以构造一个对象,将列表缩减为一个对象,将我感兴趣的每个键中的第一个插入到对象中,然后找到一个值。类似:
const interestingTypes = ['neighborhood', 'locality', 'postal_town', 'administrative_area 2', 'administrative_area_1', 'country']
const res = R.mergeAll(R.pluck('address_components', places).map((addressComponentList) => addressComponentList.reduce((memo, addressComponent) => {
if (interestingTypes.indexOf(addressComponent.types[0]) !== -1) {
if (!memo[addressComponent.types[0]]) {
memo[addressComponent.types[0]] = addressComponent.long_name
}
}
return memo
},{})))
res[R.find((type) => (Object.keys(res).indexOf(type) !== -1), interestingTypes)]
虽然用R.map/R.reduce 替换所有本机.reduce 和.map 确实可以稍微更惯用,但这并不能真正解决根本问题。
1) 即使在找到结果之后,这也会遍历列表中的每个成员。
2) 生成的结构 still 需要迭代(以 find 为例)才能真正找到最紧密的界限。
纯函数式的,最好是惰性的实现会是什么样子? Ramda 的哪些功能可以派上用场?我可以以某种方式使用镜头吗?功能构成?还有什么?
可以将原生 map/reduce 与 ramda 混合搭配吗?在可能的情况下,本机调用肯定比库调用更好吗?
【问题讨论】:
标签: javascript functional-programming ramda.js list-processing