Add `Ember.reduceComputed`, `Ember.arrayComputed`.

Reduce computed properties and computed properties that reduce an enumerable. 
Array computed properties are reduce computed properties whose value happens
to be an array.

Reduce computed properties use one-at-a-time semantics to make computations
from arrays pleasant to write without making it easy to introduce O(n²)
runtime for something that only requires O(n).

They can be chained together and retain their O(n) semantics.

A simple example:

```js
 var obj = Ember.Object.createWithMixins({
   items: Ember.A([{
     fname: "Jaime", lname: "Lannister", age: 34
   }, {
     fname: "Cersei", lname: "Lannister", age: 34
   }, {
     fname: "Robb", lname: "Stark", age: 16
   }, {
     fname: "Bran", lname: "Stark", age: 8
   }]),

    lannisters: Ember.computed.filterProperty('items', 'lname',
'Lannister'),
   lannisterSorting: Ember.A(['fname']),
   sortedLannisters: Ember.computed.sort('lannisters', 'lannisterSorting'),

    starks: Ember.computed.filterProperty('items', 'lname', 'Stark'),
   starkAges: Ember.computed.mapProperty('starks', 'age'),
   oldestStarkAge: Ember.computed.max('starkAges')
 });

  var items = obj.get('items');
 // each computed property will have to process only Tyrion to update, rather
 // than having to look through all of `items` again.
 items.pushObject(Ember.Object.create({
   fname: "Tyrion", lname: "Lannister", age: 26
 }));
```

Sugar functions include:
 - Ember.computed.max
 - Ember.computed.min
 - Ember.computed.map
 - Ember.computed.mapProperty
 - Ember.computed.filter
 - Ember.computed.filterProperty
 - Ember.computed.uniq
 - Ember.computed.intersect
 - Ember.computed.setDiff
 - Ember.computed.sort

They are all implemented with an easily used primitive.  The implementation
of
`Ember.computed.min` serves as an example:

```js
 Ember.computed.min = function (dependentKey) {
   return Ember.reduceComputed.call(null, dependentKey, {
     initialValue: Infinity,

      addedItem: function (accumulatedValue, item, changeMeta, instanceMeta)
{
       return Math.min(accumulatedValue, item);
     },

      removedItem: function (accumulatedValue, item, changeMeta,
instanceMeta) {
       if (item > accumulatedValue) {
         return accumulatedValue;
       }
     }
   });
 };
```


cc @wagenet