问题
鉴于一些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被设置为空数组?
现在剩下的
groups[groupName].push(element);
else
groups[groupName] = [element];
此处groups
是一个空对象,groupName
是一个函数。这有点令人困惑。我认为在[]中我们总是必须有一个数字,例如在数组= [1,2,3,4,5]
中我们说array[0]
是1.这三行是什么意思?谢谢。
答案 0 :(得分:3)
你可能会因为误解这一点而被原谅,以后的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(属性键)将它们排序到桶(数组)中最初为空的对象。
现在通常采用的方法是使用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
或以#7; 7z'等数字开头的键或者诸如此类的。您也可以foo[17] = 'whatever'
或foo[{}] = 'other thing'
,但这是个坏主意。密钥将无声地转换为字符串(' 17' [对象对象]'),这是常见的错误来源。您的对象属性键应该始终是字符串或符号(我提到完整性,如果您不知道符号是什么,请不要担心)。第一个使得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更新为我们带来了解构绑定,我提到它是完整性的,但它是一个比较先进的用例:
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
以上的desugars:
let sum = function(array) {
let a = array[0];
let b = array[1];
return a + b;
};