我想使用Javascript的lodash将这个数组对象转换为百分比。这是对象:
gender = {
female: [14, 33, 28, 49],
male: [33, 50, 42, 61]
}
我希望上面的对象是
genderPercent = {
female: [0.2978, 0.3975, ..., ...],
male: [0.7021, 0.6024, ..., ...]
}
这是我已经尝试过的:
_.map(gender, function (val, index, list) {
gender["male"][gender["male"].length-1] / gender["male"][gender["male"].length-1] + gender["female"][gender["female"].length-1])
});
但这似乎不起作用。
有什么建议吗? :)
(注意:我需要随时间推移的解决方案,因为我的性别数组每个月都会持续增长。)
答案 0 :(得分:2)
如果男性和女性的长度始终相同,您可以使用for循环:
var gender = {
female: [14, 33, 28, 49],
male: [33, 50, 42, 61]
}
var m = gender.male;
var f = gender.female;
var genderP = {female:[], male:[]};
for (var i = 0; i < gender.female.length; i++) {
var t = m[i] + f[i];
genderP.male.push(m[i]/t);
genderP.female.push(f[i]/t);
}
console.log(JSON.stringify(genderP, null, 2));
/*
{
"female": [
0.2978723404255319,
0.39759036144578314,
0.4,
0.44545454545454544
],
"male": [
0.7021276595744681,
0.6024096385542169,
0.6,
0.5545454545454546
]
}
*/
_.zip
和_.unzip
也可以使用:
var gender = {
female: [14, 33, 28, 49],
male: [33, 50, 42, 61]
}
var genderP = _.zipObject(['male', 'female'], _.chain(_.zip(gender.male, gender.female))
.map(function(pair) {
var t = pair[0] + pair[1]
return [pair[0] / t, pair[1] / t]
})
.unzip()
.value());
console.log(JSON.stringify(genderP, null, 2));
/*
{
"male": [
0.7021276595744681,
0.6024096385542169,
0.6,
0.5545454545454546
],
"female": [
0.2978723404255319,
0.39759036144578314,
0.4,
0.44545454545454544
]
}
*/
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/3.7.0/lodash.min.js"></script>
答案 1 :(得分:2)
仅仅for
循环怎么样?
var genderPercent = { male: [], female: [] );
for (var i=0; i<gender.male.length && i<gender.female.length; i++)
{
malePercent = gender.male[i] / (gender.male[i] + gender.female[i]);
genderPercent.male.push(malePercent);
genderPercent.female.push(1 - malePercent);
}
编辑:刚看到你的笔记。这个解决方案不会这样做,但我认为不可能在不到线性的时间内完成。你必须对每一个进行计算。
编辑2:实际上线性时间非常可扩展;我不担心。
答案 2 :(得分:1)
这对你有什么影响?我认为它符合你的要求。
var genders = {
female: [14, 33, 28, 49],
male: [33, 50, 42, 61]
};
var percents = _.map(genders, function(gender_val, gender) {
return _.map(gender_val, function(val, i) {
var opposite = gender == "male" ? "female" : "male";
return val / (val + genders[opposite][i]);
});
});
var genderPercents = _.zipObject(_.keys(genders), percents);
console.log(genderPercents);
输出以下内容:
Object {female: Array[4], male: Array[4]}
female: Array[4]
0: 0.2978723404255319
1: 0.39759036144578314
2: 0.4
3: 0.44545454545454544
male: Array[4]
0: 0.7021276595744681
1: 0.6024096385542169
2: 0.6
3: 0.5545454545454546
答案 3 :(得分:0)
如果你真的想使用数组理解(在本例中是原生的,而不是下划线),你可以这样做:
var gender = {
female: [14, 33, 28, 49],
male: [33, 50, 42, 61]
};
var genderPercent = gender.female.reduce(function(p,c,i,a) {
var f = p.female[i];
var m = p.male[i];
var sum = f+m;
p.female[i] = f/sum;
p.male[i] = m/sum;
return p;
}, gender);
如果女性和男性名单的长度不同,这将失败。
此外,它不会像每月保留结果和追加新百分比那样扩展,而不是每次都重新计算所有这些。