stack 7327056

using reduce like a baller

by Gerald Gillespie

HTML

<h1>
Gender Totals
</h1><form>
</form>

CSS

/* https://stackoverflow.com/questions/17275707/how-do-i-evenly-add-space-between-a-label-and-the-input-field-regardless-of-leng */

label {
  display: flex;
  flex-direction: row;
  justify-content: flex-end;
  text-align: right;
  width: 400px;
  line-height: 26px;
  margin-bottom: 10px;
}

input {
  height: 20px;
  flex: 0 0 200px;
  margin-left: 10px;
}

JavaScript

console.clear();
//closure
(function({
  records = [],
  targetGenders:genders = [],
   defaultOnEmptySet : result
}, fn) {

  //reduce callback extracted
  const sumGender = (desired) => ((sum, {
    gender,
    value
  }) => {
    return desired === gender ? sum + value : sum
  });

console.log({genders})
  genders.reduce((report, gender) => {
    const total = records.reduce( sumGender(gender), result );

    return fn.reporter({gender , result : total }) ;
  //    return fn.reporter(report);
  },undefined);


})( // separate data from logic 
  {
    records: [{
        value: 24,
        gender: "BOYS"
      },
      {
        value: 42,
        gender: "BOYS"
      },
      {
        value: 85,
        gender: "GIRLS"
      },
      {
        value: 12,
        gender: "GIRLS"
      },
      {
        value: 10,
        gender: "BOYS"
      }
    ],
    targetGenders: ['BOYS', 'GIRLS', 'NA'],
    defaultOnEmptySet: 0
  },
  //support
  {
    reporter({
      gender,
      result
    }) {
    console.log( { gender, result} );
      const unique = `result${Math.random()}`.replace('.','');        
      const target = document.querySelector('form');
      const wrap = document.createElement('div');
      wrap.innerHTML = `<label for="${unique}${gender}">${gender}:<input type="text" name="${unique}${gender}" value="${result}" size="${(result+'').length}"/>`;
      target.append(wrap);
    }
  }

)