从一个世纪中寻找预期寿命(Eloquent Javascript练习5.3)
Finding life expectancy from a century ( Eloquent Javascript exercise 5.3)
问题
给定一些JSON数据显示一个世纪的平均预期寿命。以下是一些示例JSON数据,因为有相当多的
'{"name": "Carolus Haverbeke", "sex": "m", "born": 1832, "died": 1905, "father": "Carel Haverbeke", "mother": "Maria van Brussel"}',
'{"name": "Emma de Milliano", "sex": "f", "born": 1876, "died": 1956, "father": "Petrus de Milliano", "mother": "Sophia van Damme"}',
'{"name": "Maria de Rycke", "sex": "f", "born": 1683, "died": 1724, "father": "Frederik de Rycke", "mother": "Laurentia van Vlaenderen"}',
'{"name": "Jan van Brussel", "sex": "m", "born": 1714, "died": 1748, "father": "Jacobus van Brussel", "mother": "Joanna van Rooten"}',
现在输出看起来像
// → 16: 43.5
// 17: 51.2
// 18: 52.8
// 19: 54.8
// 20: 84.7
// 21: 94
当然,侧面的数字指的是你在上的世纪
答案
function average(array) {
function plus(a, b) { return a + b; }
return array.reduce(plus) / array.length;
}
function groupBy(array, groupOf) {
var groups = {};
array.forEach(function(element) {
var groupName = groupOf(element);
if (groupName in groups)
groups[groupName].push(element);
else
groups[groupName] = [element];
});
return groups;
}
var byCentury = groupBy(ancestry, function(person) {
return Math.ceil(person.died / 100);
});
for (var century in byCentury) {
var ages = byCentury[century].map(function(person) {
return person.died - person.born;
});
console.log(century + ": " + average(ages));
}
// → 16: 43.5
// 17: 51.2
// 18: 52.8
// 19: 54.8
// 20: 84.7
// 21: 94
我的问题
在看了整整15分钟这个问题之后,我没有什么头绪。这个解决方案也让我有点困惑。特别是
if (groupName in groups)
但这种说法怎么可能是真的呢?组设置为空数组?
现在剩下的
groups[groupName].push(element);
else
groups[groupName] = [element];
这里groups
是一个空对象,而groupName
是一个函数。这有点令人困惑。我认为在[]中,我们总是必须有一个数字,例如在一个数组=[1,2,3,4,5]
中,我们说array[0]
是1。这三行字在说什么?非常感谢。
您误解了这一点是可以原谅的,javascript的后续版本有更好的方法来做到这一点。你真正做的是制作一桶桶相关的东西:
function groupBy(array, groupOf) {
var groups = {}; // empty (for now)
array.forEach(function(element) {
var groupName = groupOf(element); // uses the function groupOf to get a string
if (groupName in groups) // if that string is already a key in the hash
groups[groupName].push(element); // push into the array in the hash
else
groups[groupName] = [element]; // create an array in that hash with element at its first index
});
return groups;
}
这里的代码是有条件地在由组名称键入的对象中创建一个数组,例如groups['foo'][0]
将是foo组中的第一个元素。在遍历元素时,按groupName(属性键(将它们排序到bucket(数组(中最初为空的对象中。
现在通常这样做的方式是使用reduce
:
array.reduce(function(groups, element) {
var groupName = groupOf(element);
if (groupName in groups)
groups[groupName].push(element);
else
groups[groupName] = [element];
return groups;
}, {});
更新
方括号[]
运算符的多种用途:
[]
运算符可用于通过JavaScript对象上的字符串键设置/获取属性、设置/获取整数索引处的数组元素、构造数组文字或析构函数绑定。
var foo = {}; // an object literal
foo['bar'] = 'pizza'; // setting the 'bar' property.
console.log(foo['bar']); // accessing 'bar' property, prints 'pizza' to the console.
虽然上面通常写的是foo.bar
而不是foo['bar']
,在这种情况下是等效的,但方括号表示法可以做点表示法不能做的事情,比如带空格的键或变量:
foo['the pizza'] = 'pepperoni';
var str = 'whatever';
foo[str] = 'psssh yeah right';
console.log(foo['whatever'] === foo.whatever === foo[str]); // true
或者是以数字开头的键,比如"7z"之类的。您也可以执行foo[17] = 'whatever'
或foo[{}] = 'other thing'
,但这是个坏主意。键将被静默地转换为字符串("17"answers"[对象对象]"(,这是常见的错误源。您的对象属性键应该始终是字符串或符号(为了完整起见,我提到了这一点,如果您不知道符号是什么,请不要担心(。第一个增加了使foo看起来像数组的混乱,因为它们使用相同的方括号访问,但使用整数标记:
var arr = []; // an array literal
arr.push('sausage'); // adds an element
console.log(arr[0]); // accesses the first element, prints 'sausage'
arr[0] = 'veggie'; // changes the element at index 0
console.log(arr[0]); // prints 'veggie'
我们在上面构造了一个空数组,但它们不一定是空的:
var ints = [0, 1, 2, 3]; // a four element array
var single = [element]; // creates a one-element array with the value of the variable element
高级使用
2015年对JavaScript的更新为我们带来了destructuring bind,我提到它是为了完整性,但它是一个相对高级的用例:
let arr = [1, 'qux'];
let [something, otherthing] = arr;
console.log(something); // 1
console.log(otherthing); // 'qux'
减温器上方的第二条管线连接至以下装置:
let something = arr[0];
let otherthing = arr[1];
它也可以用于函数定义:
let sum = function([a, b]) { return a + b; }; // note the brackets
let arr = [2, 8];
console.log(sum(arr)); // 10
上述减温器至:
let sum = function(array) {
let a = array[0];
let b = array[1];
return a + b;
};
- 为什么不't Javascript对我的输入值进行了一些重新检查
- 创建一个类似链接的按钮,并通过Javascript函数打开一个新的弹出窗口
- Eloquent JavaScript递归示例如何终止为返回1,但仍然输出指数值
- 关于来自 Eloquent Javascript 的 Javascript 代码
- "Eloquent Javascript“;递归练习
- Eloquent JavaScript一书中的奇怪命令
- Eloquent JavaScript,第 2 版,练习 5.3 历史预期寿命
- Eloquent JavaScript,第 2 版,第 5 章高阶函数
- JavaScript function to reverseArrayInPlace -- Eloquent JavaS
- Eloquent Javascript第二名.第4章.计算相关性.Lycarthorpe的日志-〔定义的索引〕第1部分
- Eloquent Javascript列表返回undefined,Why
- Eloquent Javascript中的练习4.4——startsWith()和.slice
- Eloquent javascript中的循环示例没有运行
- Eloquent Javascript:未捕获的类型错误:无法读取属性'indexOf'的未定义
- 深度比较(Eloquent Javascript第4章):代码在测试用例中失败
- Eloquent Javascript: Chessboard
- Eloquent Javascript-第4章关于Arguments对象
- 需要帮助理解Eloquent Javascript中的递归函数示例
- 变量组合在一行 indexOf 方法(Eloquent Javascript)中
- 从一个世纪中寻找预期寿命(Eloquent Javascript练习5.3)