React JS:重构 Redux 选择器
React JS: Refactoring Redux Selectors
我正在使用多个选择器来获取设置 Google 地图的边界。他们基本上 return 数据中的最低和最高 lat/lng 点。代码有效,但我觉得这真的很乱,可以重构,但我不太确定如何重构。
代码如下:
const getMinLat = data =>
data.reduce((prev, current) => {
return prev.coords[0] < current.coords[0] ? prev : current
})
const getMaxLat = data =>
data.reduce((prev, current) => {
return prev.coords[0] > current.coords[0] ? prev : current
})
const getMinLng = data =>
data.reduce((prev, current) => {
return prev.coords[1] < current.coords[1] ? prev : current
})
const getMaxLng = data =>
data.reduce((prev, current) => {
return prev.coords[1] > current.coords[1] ? prev : current
})
const getBounds = data => [
{
lat: getMinLat(data).coords[0],
lng: getMinLng(data).coords[1],
},
{
lat: getMaxLat(data).coords[0],
lng: getMaxLng(data).coords[1],
},
]
也许这个
const getMin = (data, index) =>
data.reduce((prev, current) => (prev.coords[index] < current.coords[index] ? prev : current))
.coords[index];
const getMax = (data, index) =>
data.reduce((prev, current) => (prev.coords[index] > current.coords[index] ? prev : current))
.coords[index];
const getBounds = data => [
{
lat: getMin(data, 0),
lng: getMin(data, 1)
},
{
lat: getMax(data, 0),
lng: getMax(data, 1)
}
];
你可以使用Array.map()
:
让它更简洁
const getCoordsArray = (data, index) =>
data.map(o => o.coords[index]);
const getMin = (data, index) =>
Math.min(...getCoordsArray(data, index));
const getMax = (data, index) =>
Math.max(...getCoordsArray(data, index));
const getBounds = data => [getMin, getMax]
.map(m => ({
lat: m(data, 0),
lng: m(data, 1),
}));
只遍历列表一次:
const getBounds = data =>
data.reduce(
([
{lat: minLat, lng: minLng},
{lat: maxLat, lng: maxLng}
],
{coords: [lat, lng]}
) =>
[
{
lat: Math.min(minLat, lat),
lng: Math.min(minLng, lng)
},
{
lat: Math.max(maxLat, lat),
lng: Math.max(maxLng, lng)
}
],
[{lat: Infinity, lng: Infinity}, {lat: -Infinity, lng: -Infinity}]
)
我提前同意可读性不是这里的优势。但它只通过列表一次。
此外,在习惯了解构语法之后,很明显 Math.max
和 maxLng/maxLat
一起减少了使用错误变量的可能性
[UPD] 并且不需要使用 Infinity/-Infinity
作为起始值(我用它们来突出背后的想法)。对于 longitude/latitude 我们可以使用 180/-180
作为最极端的值
我正在使用多个选择器来获取设置 Google 地图的边界。他们基本上 return 数据中的最低和最高 lat/lng 点。代码有效,但我觉得这真的很乱,可以重构,但我不太确定如何重构。
代码如下:
const getMinLat = data =>
data.reduce((prev, current) => {
return prev.coords[0] < current.coords[0] ? prev : current
})
const getMaxLat = data =>
data.reduce((prev, current) => {
return prev.coords[0] > current.coords[0] ? prev : current
})
const getMinLng = data =>
data.reduce((prev, current) => {
return prev.coords[1] < current.coords[1] ? prev : current
})
const getMaxLng = data =>
data.reduce((prev, current) => {
return prev.coords[1] > current.coords[1] ? prev : current
})
const getBounds = data => [
{
lat: getMinLat(data).coords[0],
lng: getMinLng(data).coords[1],
},
{
lat: getMaxLat(data).coords[0],
lng: getMaxLng(data).coords[1],
},
]
也许这个
const getMin = (data, index) =>
data.reduce((prev, current) => (prev.coords[index] < current.coords[index] ? prev : current))
.coords[index];
const getMax = (data, index) =>
data.reduce((prev, current) => (prev.coords[index] > current.coords[index] ? prev : current))
.coords[index];
const getBounds = data => [
{
lat: getMin(data, 0),
lng: getMin(data, 1)
},
{
lat: getMax(data, 0),
lng: getMax(data, 1)
}
];
你可以使用Array.map()
:
const getCoordsArray = (data, index) =>
data.map(o => o.coords[index]);
const getMin = (data, index) =>
Math.min(...getCoordsArray(data, index));
const getMax = (data, index) =>
Math.max(...getCoordsArray(data, index));
const getBounds = data => [getMin, getMax]
.map(m => ({
lat: m(data, 0),
lng: m(data, 1),
}));
只遍历列表一次:
const getBounds = data =>
data.reduce(
([
{lat: minLat, lng: minLng},
{lat: maxLat, lng: maxLng}
],
{coords: [lat, lng]}
) =>
[
{
lat: Math.min(minLat, lat),
lng: Math.min(minLng, lng)
},
{
lat: Math.max(maxLat, lat),
lng: Math.max(maxLng, lng)
}
],
[{lat: Infinity, lng: Infinity}, {lat: -Infinity, lng: -Infinity}]
)
我提前同意可读性不是这里的优势。但它只通过列表一次。
此外,在习惯了解构语法之后,很明显 Math.max
和 maxLng/maxLat
一起减少了使用错误变量的可能性
[UPD] 并且不需要使用 Infinity/-Infinity
作为起始值(我用它们来突出背后的想法)。对于 longitude/latitude 我们可以使用 180/-180
作为最极端的值