Skip to content Skip to sidebar Skip to footer

Ramda Js Best Way To Get The Tightest Geographic Bound

I am attempting to use the Google Places API in order to get the place name of a location I am in. The returned data structure has the following types: descriptor1: 'street number'

Solution 1:

One approach would be to create a lazy version of R.reduceRight:

const lazyReduceR = R.curry((fn, acc, list) => {
  function_lazyReduceR(i) {
    return i === list.length
      ? acc
      : fn(list[i], () => _lazyFoldR(i + 1))
  }
  return_lazyReduceR(0)
})

This could then be used to create a function that will find the minimum element of a (non-empty) list, with a known lower bound:

const boundMinBy = R.curry((byFn, lowerBound, list) =>lazyReduceR((x, lzMin) => {
    if (byFn(x) === lowerBound) {
      return x;
    } else {
      const min = lzMin()
      returnbyFn(x) < byFn(min) ? x : min
    }
  }, list[0], R.tail(list)))

If the lower bound is ever encountered, the recursion stops and returns that result immediately.

With boundMinBy available, we can create a lookup table of address types to sort order values:

constsortOrder= {
  neighborhood:0,
  locality:1,
  postal_town:2,
  administrative_area_level_2:3,
  administrative_area_level_1:4,
  country:5
}

Along with a function that will produce a sort order value for a given address component:

const sortOrderOfAddress = address => sortOrder[address.types[0]]

And then we can compose it altogether with a pipeline such as:

const process = R.pipe(
  R.prop('places'),
  R.chain(R.pipe(
    R.prop('address_components'),
    R.unless(
      R.isEmpty,
      R.pipe(
        boundMinBy(sortOrderOfAddress, 0),
        R.prop('long_name'),
        R.of
      )
    )
  ))
)

R.chain is used above to concatenate the addresses of all places and filter out any addresses of places where address_components is empty.

I have included an example in the snippet below if you want to test it out with some data.

const lazyReduceR = R.curry((fn, acc, list) => {
  function_lazyReduceR(i) {
    return i === list.length
      ? acc
      : fn(list[i], () =>_lazyReduceR(i + 1))
  }
  return_lazyReduceR(0)
})

const boundMinBy = R.curry((byFn, lowerBound, list) =>lazyReduceR((x, lzMin) => {
    if (byFn(x) === lowerBound) {
      return x;
    } else {
      const min = lzMin()
      returnbyFn(x) < byFn(min) ? x : min
    }
  }, list[0], R.tail(list)))

const sortOrder = {
  neighborhood: 0,
  locality: 1,
  postal_town: 2,
  administrative_area_level_2: 3,
  administrative_area_level_1: 4,
  country: 5
}

constsortOrderOfAddress = address => sortOrder[address.types[0]]

const process = R.pipe(
  R.prop('places'),
  R.chain(R.pipe(
    R.prop('address_components'),
    R.unless(
      R.isEmpty,
      R.pipe(
        boundMinBy(sortOrderOfAddress, 0),
        R.prop('long_name'),
        R.of
      )
    )
  ))
)

////const data = {
  places: [{
    address_components: [{
      long_name: 'a',
      types: ['country']
    }, {
      long_name: 'b',
      types: ['neighborhood']
    }, {
      long_name: 'c',
      types: ['postal_town']
    }]
  }, {
    address_components: [{
      long_name: 'd',
      types: ['country']
    }, {
      long_name: 'e',
      types: ['locality']
    }, {
      long_name: 'f',
      types: ['administrative_area_level_2']
    }]
  }]
}

console.log(process(data))
<scriptsrc="//cdnjs.cloudflare.com/ajax/libs/ramda/0.23.0/ramda.min.js"></script>

Solution 2:

And is it ok to mix and match native map/reduce with ramda?

Absolutely. But you have to also consider the cognitive costs involved in combining them.

Surely native calls are better than library invocations whenever possible?

Better how? Library functions are designed to avoid some unfortunate complexity in the specifications for the native functions.

Moreover, when Ramda's core functions were written, they had significantly better performance than their native counterparts. That may have changed as the native engines have progressed and as Ramda's functions have taken on more complexity. But it's also quite possible that it hasn't.

Post a Comment for "Ramda Js Best Way To Get The Tightest Geographic Bound"