1

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?

7
  • what result do you expect? Commented Mar 18, 2022 at 16:06
  • @NinaScholz I have updated the question with non functional way of to return both, I am new to the functional way Can this be achieved in a functional way? Commented Mar 18, 2022 at 16:20
  • In your example, routeOne is fastest but both the TukTuk and Car would cover routeOne at the same time, in 1.5 time units. So which vehicle takes precedence? Commented Mar 18, 2022 at 16:30
  • @Tim Car takes the preference since the vehicles array is already in that order. that is taken care of Commented Mar 18, 2022 at 16:34
  • @HariHaravelan, in that case please see my answer. Commented Mar 18, 2022 at 16:42

3 Answers 3

1

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

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

1 Comment

the code in a loop may affect variables defined before it or code that runs after it is not considered a pure function, this was the expectation Thank you!
1

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

Comments

1

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

3 Comments

there was a typo, I've fixed it
I have a similar implementation, can you help with the functional way @palmarbg
what is functional way?

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.