Lodash - _.some () with condition / counter

Consider the following task:

We have a list of average daily temperatures in different European cities.

{ Hamburg: [14, 15, 16, 14, 18, 17, 20, 11, 21, 18, 19,11 ],
  Munich: [16, 17, 19, 20, 21, 23, 22, 21, 20, 19, 24, 23],
  Madrid: [24, 23, 20, 24, 24, 23, 21, 22, 24, 20, 24, 22],
  Stockholm: [16, 14, 12, 15, 13, 14, 14, 12, 11, 14, 15, 14],
  Warsaw: [17, 15, 16, 18, 20, 20, 21, 18, 19, 18, 17, 20] }

We want to sort these cities into two groups: “warm” and “hot”. “warm” should be cities that have at least 3 days with temperatures above 19. “hot” should be cities where the temperature is more than 19 every day.

What I did in the end:

const _ = require('lodash');

let cities = {
    Hamburg: [14, 15, 16, 14, 18, 17, 20, 11, 21, 18, 19,11 ],
    Munich: [16, 17, 19, 20, 21, 23, 22, 21, 20, 19, 24, 23],
    Madrid: [24, 23, 20, 24, 24, 23, 21, 22, 24, 20, 24, 22],
    Stockholm: [16, 14, 12, 15, 13, 14, 14, 12, 11, 14, 15, 14],
    Warsaw: [17, 15, 16, 18, 20, 20, 21, 18, 19, 18, 17, 20]
};

let isHot = (degrees) => {
  return degrees > 19;
};

function getMinCategories(cities) {

    let res = {
        hot: [],
        warm: []
    };
    _.forEach(cities, function(val,key) {
      if(_.every(val, isHot)){
        res.hot.push(key);
      } else if(_.sumBy(val, degree => isHot(degree) ? 1 : 0) > 2){
        res.warm.push(key);
      }

    });
    return res;
}

console.log(getMinCategories(cities)); // prints { hot: [ 'Madrid' ], warm: [ 'Munich', 'Warsaw' ] } which is correct

Is there a more elegant way to check "at least 3 days with a temperature> 19" instead of using the function _.sumBy? Perhaps using _.some()?

+4
source share
5 answers

I have included vanilla js and lodash solution.

Vanilla js

, , :

tempaturesArray.filter((t) => t > 19).length

vanilla JS, Array#reduce:

const result = Object.keys(cities).reduce(( obj, city ) => {
  const days = cities[city].filter((t) => t > 19).length;
  const climate = days === cities[city].length ? 'hot' : (days >= 3 ? 'warm' : null);

  climate && obj[climate].push(city);

  return obj;
}, { hot: [], warm: []});

const cities = {
  Hamburg: [14, 15, 16, 14, 18, 17, 20, 11, 21, 18, 19,11 ],
  Munich: [16, 17, 19, 20, 21, 23, 22, 21, 20, 19, 24, 23],
  Madrid: [24, 23, 20, 24, 24, 23, 21, 22, 24, 20, 24, 22],
  Stockholm: [16, 14, 12, 15, 13, 14, 14, 12, 11, 14, 15, 14],
  Warsaw: [17, 15, 16, 18, 20, 20, 21, 18, 19, 18, 17, 20]
};

const result = Object.keys(cities).reduce(( obj, city ) => {
  const days = cities[city].filter((t) => t > 19).length;
  const climate = days === cities[city].length ? 'hot' : (days >= 3 ? 'warm' : null);
  
  climate && obj[climate].push(city);
  
  return obj;
}, { hot: [], warm: []});
        
console.log(result);
Hide result

lodash

_.mapValues() // , _.invertBy(), . _.sumBy() , _.every(), :

const result = _(cities)
  .mapValues((temperature, country) => {
    const days = _.sumBy(temperature, (t) => t > 19);
    return days === temperature.length ? 'hot' : (days >= 3 ? 'warm' : 'cold');
  })
  .invertBy()
  .pick(['warm', 'hot'])
  .value();

const cities = {
  Hamburg: [14, 15, 16, 14, 18, 17, 20, 11, 21, 18, 19,11 ],
  Munich: [16, 17, 19, 20, 21, 23, 22, 21, 20, 19, 24, 23],
  Madrid: [24, 23, 20, 24, 24, 23, 21, 22, 24, 20, 24, 22],
  Stockholm: [16, 14, 12, 15, 13, 14, 14, 12, 11, 14, 15, 14],
  Warsaw: [17, 15, 16, 18, 20, 20, 21, 18, 19, 18, 17, 20]
};

const result = _(cities)
  .mapValues((temperature, country) => {
    const days = _.sumBy(temperature, (t) => t > 19);
    return days === temperature.length ? 'hot' : (days >= 3 ? 'warm' : 'cold');
  })
  .invertBy()
  .pick(['warm', 'hot'])
  .value();
        
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.2/lodash.min.js"></script>
Hide result
+3

pickBy :

var cities = {
  "Hamburg":   [14,15,16,14,18,17,20,11,21,18,19,11],
  "Munich":    [16,17,19,20,21,23,22,21,20,19,24,23],
  "Madrid":    [24,23,20,24,24,23,21,22,24,20,24,22],
  "Stockholm": [16,14,12,15,13,14,14,12,11,14,15,14],
  "Warsaw":    [17,15,16,18,20,20,21,18,19,18,17,20]
}

var hotCities = _(cities)
  .pickBy(temps => _(temps).map(x => x > 19).every())
  .value();
var warmCities = _(cities)
  .pickBy((temps, name) => hotCities[name] === undefined) // already hot
  .pickBy(temps => _(temps).filter(x => x > 19).size() >= 3)
  .value();

console.log(hotCities)
console.log(warmCities)
<script src="https://cdn.jsdelivr.net/lodash/4.17.2/lodash.min.js"></script>
Hide result
+2

mixin ' x ":

_.mixin( { 'atLeast': function(list, times, predicate){
    return _.filter(list, function(item){
        return predicate(item);
    }).length >= times;
}});

:

// helper function to work out if a city is hot
let hotCity = city => _.atLeast(city, 3, isHot)

let hotCities = _.chain(cities)
    .pickBy(hotCity)
    .keys()
    .value();
+1

:

 _.filter(cities ,function(i){
                        var f=_.filter(i,function(t){return t>19});
                         return f.length>2;
});
0

_.reduce _.filter

_.reduce(cities, (result, temps, town) => {
    return _.chain(temps)
        .filter((temp) => {
            return temp > 19;
        })
        .thru((filtTemps) => {
            let kind;
            kind = filtTemps.length >= 3 ? 'warm' : kind;
            kind = filtTemps.length === temps.length ? 'hot' : kind;
            if (!_.isUndefined(kind)) {
                 result[kind].push(town);
            }
            return result;
        })
        .value();

}, {
    hot: [],
    warm: []
});
0

Source: https://habr.com/ru/post/1662925/


All Articles