考虑以下任务:
我们列出了不同欧洲城镇的日平均气温。
{ 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] }
我们希望将这些城镇分为两组:“温暖”和“热”。 “温暖”应该 是温度大于19的城镇,至少有3天。“热” 应该是每天温度超过19的城镇。
我最终做的是:
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
有没有更优雅的方法来检查“至少3天温度> 19”而不是使用_.sumBy
功能?也许使用_.some()
?
答案 0 :(得分:4)
我已经包含了一个香草js解决方案和一个lodash一个。
Vanilla JS
您可以使用过滤器计算符合条件的天数:
tempaturesArray.filter((t) => t > 19).length
你可以使用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);
<强> 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>
答案 1 :(得分:2)
您可以像这样使用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)
&#13;
<script src="https://cdn.jsdelivr.net/lodash/4.17.2/lodash.min.js"></script>
&#13;
答案 2 :(得分:1)
如何创建一个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();
答案 3 :(得分:0)
使用过滤器:
Work
答案 4 :(得分: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: []
});