-1

I need to distribute certain amounts to array of people according to their score. The rule is that their demands are met according to their position with whatever remains. In JavaScript using Lo-Dash (JSBin):

var amount = 1000,
  people = [
    { name : 'Joe', score: 40, demand: 400},
    { name : 'Sue', score: 30, demand: 350},
    { name : 'Kim', score: 25, demand: 300},
    { name : 'Ron', score: 20, demand: 250}
  ];

function  distribute(people, amount){
   return _.map(_.sortBy(people,'need'),function(person){      
     var ration = Math.min(person.demand,amount); 
     amount -= ration; // This is the state (mutation) that I want to avoid
     return _.assign(person,{ ration: ration})
 });
}
console.log(distribute(people, amount));

Result:

[{  demand: 400,  name: "Joe",  ration: 400,  score: 40}, 
 {  demand: 350,  name: "Sue",  ration: 350,  score: 30}, 
 {  demand: 300,  name: "Kim",  ration: 250,  score: 25}, 
 {  demand: 250,  name: "Ron",  ration:   0,  score: 20}]

Since the solution depends on the order, is it possible to change this code to make it purely functional?

Qantas 94 Heavy
  • 15,750
  • 31
  • 68
  • 83
slobodan.blazeski
  • 1,040
  • 9
  • 20
  • That solution seems to be okay. What is your question about? – Thomas Junk Jul 27 '14 at 09:52
  • It uses mutation,since I depend on mutating amount. I would prefer functional solution if possible. – slobodan.blazeski Jul 27 '14 at 09:56
  • 2
    This question appears to be off-topic because it is about code review. It should belong to http://codereview.stackexchange.com/ – Pavlo Jul 27 '14 at 10:00
  • 1
    _"This question does not appear to be about programming within the scope defined in the [help center](http://stackoverflow.com/help/on-topic)."_ By what reading of the help center article do you think this question is not about programming? – Daniel Darabos Jul 27 '14 at 10:16
  • 1
    I believe that the problem is general enough of using intermediate state and should be covered by "a specific programming problem" of turning iterative into purely functional solution. The code supplied was for illustration of the mutation based solution and to provide comparison results. – slobodan.blazeski Jul 27 '14 at 10:32

1 Answers1

0

The functional solution is a fold:

function distribute(people, amount) {
  return _.foldl(_.sortBy(people, 'score'), function(result, person) {
    var ration = Math.min(person.demand, result.remaining);
    var resultPerson = _.assign(person, { ration: ration });
    return { people: result.people.concat(resultPerson),
             remaining: result.remaining - ration };
  }, { people: [], remaining: amount }).people;
}
Daniel Darabos
  • 26,991
  • 10
  • 102
  • 114