0

I am using several selectors to get the boundaries on which to set my Google Maps. They basically return the lowest and highest lat/lng points from the data. The code works but I feel this is really messy and can be re-factored, but i'm not too sure how.

Here is the code:

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],
  },
]

3 Answers 3

1

just traverse list once:

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}]
    )

I agree in advance that readability is not the advantage here. But it goes through list just once.

Also after getting used to destructuring syntax it's quite clear that Math.max and maxLng/maxLat goes together to decrease possibility of using wrong variable

[UPD] and there is no need to use Infinity/-Infinity as start values(I used them to highlight idea behind). for longitude/latitude we may use 180/-180 as most extreme values

Sign up to request clarification or add additional context in comments.

Comments

1

Maybe this

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)
  }
];

Comments

1

You can make it more concise by using 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),
  }));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.