I have two arrays vehicles
and routes
, given below
const vehicles = [{ name: 'TukTuk', maxSpeed: 12 },
{ name: 'Bike', maxSpeed: 10 },
{ name: 'Car', maxSpeed: 20 }];
const routes = [{ name: 'routeOne' , distance: 18, allowedSpeed: 12 }
, {name: 'routeTwo', distance: 20, allowedSpeed: 10 }];
There is this rule, the vehicle would travel in the route's allowed speed even it can ride faster
That is covered written in this function
const getTravelTime = (vehicle, route) => {
return route.allowedSpeed < vehicle.maxSpeed ? (route.distance / route.allowedSpeed) : (route.distance / vehicle.maxSpeed);
};
The objective is to find the fastest route and vehicle for the Journey
I have a implementation which is not functional
const getFastestJourney = (vehicles,routes) => {
let fastestTime = Infinity;
let fastestRoute,fastestVehicle;
for(let i =0;i < vehicles.length; i ){
for(let j=0;j< routes.length;j ){
let travelTime = getTravelTime(vehicles[i],routes[j]);
if(travelTime < fastestTime){
fastestVehicle = vehicles[i];
fastestRoute = routes[j];
fastestTime = travelTime;
}
}
}
return {
route: fastestRoute,
vehicle: fastestVehicle,
};
};
how do I achieve that in the functional way?
CodePudding user response:
You could get an array of all combinations of vehicles
and routes
and their travel time and reduce this array by looking for shorter time and faster vehicle.
const
vehicles = [{ name: 'TukTuk', maxSpeed: 12 }, { name: 'Bike', maxSpeed: 10 }, { name: 'Car', maxSpeed: 20 }],
routes = [{ name: 'routeOne' , distance: 18, allowedSpeed: 12 }, {name: 'routeTwo', distance: 20, allowedSpeed: 10 }],
getTravelTime = (vehicle, route) => route.distance / (route.allowedSpeed < vehicle.maxSpeed ? route.allowedSpeed : vehicle.maxSpeed),
result = vehicles
.flatMap(v => routes.map(r => ({
vehicle: v.name,
maxSpeed: v.maxSpeed,
route: r.name,
time: getTravelTime (v, r)
})))
.reduce((a, b) =>
a.time === b.time && a.maxSpeed > b.maxSpeed ||
a.time < b.time
? a
: b
);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
CodePudding user response:
Here is one way to find the fastest vehicle/route:
const vehicles = [
{name: 'TukTuk',maxSpeed: 12},
{name: 'Bike', maxSpeed: 10},
{name: 'Car', maxSpeed: 20}
]
const routes = [
{name: 'routeOne', distance: 18, allowedSpeed: 12},
{name: 'routeTwo', distance: 20, allowedSpeed: 10}
]
function getFastestRoute(vehicles, routes) {
let times = []
// Calculate times for each route/vehicle combo
routes.forEach(r => {
vehicles.forEach(v => {
times.push({
route: r.name,
vehicle: v.name,
time: r.distance / Math.min(r.allowedSpeed, v.maxSpeed)
})
})
})
// Find fastest time and route
let fastest = times.reduce((prev, curr) => prev.time < curr.time ? prev : curr)
return fastest
}
console.log(getFastestRoute(vehicles, routes))
If you need all fastest vehicles and routes, you can use this instead:
let fastest = times.filter(f => f.time === Math.min(...times.map(t => t.time)))
CodePudding user response:
const vehicles = [{ name: 'TukTuk', maxSpeed: 12 },
{ name: 'Bike', maxSpeed: 10 },
{ name: 'Car', maxSpeed: 20 }];
const routes = [{ name: 'routeOne' , distance: 18, allowedSpeed: 12 }
, {name: 'routeTwo', distance: 20, allowedSpeed: 10 }];
function fast(cars, roads){
let maxSpeed = -1, speedIndex=0;
for(let i in cars)
if(maxSpeed < cars[i].maxSpeed){
maxSpeed = cars[i].maxSpeed;
speedIndex = i;
}
let minTime = Infinity, roadIndex=0;
for(let i in roads)
if(minTime > roads[i].distance/Math.min(roads[i].allowedSpeed, maxSpeed)){
minTime=roads[i].distance/Math.min(roads[i].allowedSpeed, maxSpeed);
roadIndex=i;
}
return [cars[speedIndex].name, roads[roadIndex].name]
}
console.log(fast(vehicles, routes))
Or if you don't like for loops
const vehicles = [{ name: 'TukTuk', maxSpeed: 12 },
{ name: 'Bike', maxSpeed: 10 },
{ name: 'Car', maxSpeed: 20 }];
const routes = [{ name: 'routeOne' , distance: 18, allowedSpeed: 12 },
{name: 'routeTwo', distance: 20, allowedSpeed: 10 }];
function fast(cars, roads){
const maxSpeed = Math.max(...cars.map(e => e.maxSpeed))
const times = roads.map(e => e.distance/Math.min(e.allowedSpeed, maxSpeed));
const minTime = Math.min(...times)
const carIndex = cars.findIndex(e => e.maxSpeed==maxSpeed)
const roadIndex = times.findIndex(e => e==minTime)
return [cars[carIndex], roads[roadIndex]]
}
console.log(fast(vehicles, routes))