寻找一个世纪的预期寿命(Eloquent Javascript exercise 5.3)

时间:2016-07-05 18:30:25

标签: javascript

问题

鉴于一些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.这三行是什么意思?谢谢。

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;
};