问题
The old way of doing it
let min = Number.MAX_VALUE;
for (let item of food) {
let current = Problem.manhattan_distance(player, item);
if (current > min){
min = current;
this.goal = item;
}
}
From the code you can see that after the for cycle has ended in the this.goal
variable we will have the food item with the lowest Manhattan distance.
Note: Problem.manhattan_distance(player, item)
returns an integer
I want to achieve the same result using JavaScript functional programming maybe something along these lines
let smallest_mhd: number = food
.map((item) => Problem.manhattan_distance(player, item))
.reduce((a, b) => Math.min(a, b));
but this returns just the lowest number, what i want is the OBJECT that has the lowest number.
回答1:
If your method isn't particularly expensive (like simple math), you can simply do something like this:
const calcSomething = o => o.id;
const values = [{ id: 1 }, { id: 2 } , { id: 3 }];
const result = values.reduce((result, v) => calcSomething(v) < calcSomething(result) ? v : result);
console.log(result);
If it is more expensive, then you could do something like this:
const calcSomething = o => o.id;
const values = [{ id: 1 }, { id: 2 } , { id: 3 }];
const result = values.reduce((result, obj) => {
const calc = calcSomething(obj);
return calc < result.calc ? { obj, calc } : result
}, { obj: null, calc: Number.MAX_VALUE });
console.log(result.obj);
This avoids having to rerun the calculation. The key is to make sure you initialize it with an object that has the initial calculation set to the maximum value, so it will be overridden by the first loop.
This second approach is like creating an map
of pairs of calcuation and objects, but without needing the extra loop that comes from a separate map (since you don't need all of them, just the minimum one).
回答2:
Something like this probably:
let smallest_mhd: number = food
.map((item) => [item, Problem.manhattan_distance(player, item)])
.reduce((a, b) => a[1] < b[1] ? a : b);
the key is not to loose the mapping between the item and its distance value. The object is then the index 0
of the result.
回答3:
You could check the property and return the object. A the the end take the item
property as result.
let smallest_mhd = food
.map(item => ({ item, value: Problem.manhattan_distance(player, item) }))
.reduce((a, b) => a.value < b.value ? a : b)
.item;
来源:https://stackoverflow.com/questions/50845210/how-to-find-the-object-which-has-the-lowest-property-from-a-list-of-objects-usin