Skip to content

Instantly share code, notes, and snippets.

@anatomic
Last active September 13, 2018 14:13
Show Gist options
  • Save anatomic/6eca72d6ed9e1f09c61edd478b0c030c to your computer and use it in GitHub Desktop.
Save anatomic/6eca72d6ed9e1f09c61edd478b0c030c to your computer and use it in GitHub Desktop.
const API_BASE = "https://api.citybik.es";
const fetchP = require("node-fetch");
const {
Async,
pipeK,
propOr,
} = require("crocks");
const fetch = Async.fromPromise(fetchP);
const json = response =>
Async((rej, res) =>
response
.json()
.then(res)
.catch(res)
);
const fetchJson = pipeK(fetch, json);
const fetchNetworks = () => fetchJson(API_BASE + "/v2/networks");
const fetchNetworkById = id =>
fetchJson(API_BASE + "/v2/networks/" + id).map(propOr({}, "network"));
module.exports = {
fetchNetworks,
fetchNetworkById
}
const { fetchNetworks, fetchNetworkById } = require("./cityBikes");
const {
Async,
Pair,
Pred,
Sum,
assign,
bimap,
concat,
fanout,
filter,
isString,
map,
mapProps,
mapReduce,
merge,
pick,
pipe,
propOr,
propPathOr,
traverse,
valueOf
} = require("crocks");
/**
* Using the CityBikes API (http://api.citybik.es/v2/):
* 1. Get all networks and filter down to just those in GB
* 2. Get all stations for each of the GB networks
* 3. Sum the number of free_bikes for each network
* 4. Output a list sorted by number of free bikes
*/
const isGb = Pred(isString)
.concat(Pred(x => x === "GB"))
.contramap(propPathOr(null, ["location", "country"]));
const calculateFreeBikes = pipe(
fanout(
pick(["name", "location"]),
pipe(
propOr([], "stations"),
mapReduce(
s => Pair(Sum(s.free_bikes), Sum(s.empty_slots)),
concat,
Pair(Sum(0), Sum(0))
),
bimap(valueOf, valueOf),
p => ({ freeBikes: p.fst(), emptySlots: p.snd() })
)
),
merge(assign),
mapProps({
location: propOr("", "city")
})
);
const getNetworks = pipe(
propOr([], "networks"),
filter(isGb),
traverse(
Async,
pipe(propOr("", "id"), fetchNetworkById, map(calculateFreeBikes))
)
);
const getFreeBikes = propOr(0, "freeBikes");
const sortByFreeBikes = n =>
n.sort((a, b) => getFreeBikes(b) - getFreeBikes(a));
fetchNetworks()
.chain(getNetworks)
.map(sortByFreeBikes)
.fork(console.error, console.log);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment