2017-02-13 16 views
1

Я читал документацию функции уменьшения в javascript, и я застрял в этом примере.Как уменьшить работу здесь?

var names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice']; 
var countedNames = names.reduce(function(allNames, name) { 

    if (name in allNames) { 
     allNames[name]++; 
    } else { 
     allNames[name] = 1; 
    } 

    return allNames; 
}, {}); 

console.log(countedNames); 

Как это вывод:

{ 'Алиса': 2, 'Bob': 1, 'Tiff': 1, 'Брюс': 1}

вместо из

{2,1,1,1}

+3

Объект буквального должен иметь свойства, чтобы присвоить значения. Ваш ожидаемый результат недействителен javascript – charlietfl

+0

Поместите 'var allNames = {}' вверху и измените это: 'names.reduce (function (allNames, name) {...' на это: 'names.forEach (function (name) {... ', и это в основном то же самое. Главное отличие состоит в том, что' .reduce() 'передает возвращаемое вами значение из обратного вызова обратно в обратный вызов на следующей итерации. –

ответ

1

Вы передаете анонимную функцию и пустой объект методу уменьшения. Если вы посмотрите на документы на MDN для уменьшения: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce

Вы можете видеть, что он принимает функцию обратного вызова и начальное значение. В этом случае вы передаете пустой объект {} в качестве начального значения (см. От второй до последней строки)

Метод reduce затем «применяет функцию к аккумулятору и каждому значению массива (слева направо) чтобы уменьшить его до одного значения."

Это одно значение начинается как пустой объект, а затем свойства, добавленные получить и увеличивается в этом объекте на основе условной логики в теле функции обратного вызова

Ваша линия:.

allNames[name] = 1 

служит для создания свойства с именем name и присваивает свойству значение 1.

Эта линия:

allNames[name] += 1; 

Простая установка существующего объекта.

Я хотел бы далее предположить, что пример кода не хватает форматирование, которое будет дополнительно уточнить код:

var names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice']; 
var obj = {}; 

var countedNames = names.reduce(function(allNames, name) { 
    if (name in allNames) { 
    allNames[name]++; 
    } else { 
    allNames[name] = 1; 
    } 

    return allNames; 
}, obj); 

console.log(countedNames); 
+0

Моя проблема заключалась в том, что я не знал как работает инициализация боковых объектов объекта. Спасибо за разъяснение этого –

0

Итак, reduce возьмет array и уменьшит его до одного значения. В вашем случае вы находитесь reduce, используя array имен до хэша, который содержит имена и количество, сколько раз это имя существует в вашем array. Последний аргумент reduce - начальное начальное значение. В этом случае вы даете ему пустой object. Этот object представлен функцией allNames в вашей функции обратного вызова. Итак, для каждого name в вашем array вы указываете allNames, если name уже существует. Если это так, то увеличивайте счетчик на name, иначе установите его на 1.

0

Функция уменьшения начинается с начального значения, к которому последуют последующие «сокращения» входящих данных. В этом случае это начальное значение равно {}, то есть объектный литерал, со второй последней строки вашего кода. Постепенно накапливаемое значение, к которому будут применены все новые модификации, в этом случае называется allNames. Когда функция reduce делает что-то до allNames[name], она что-то делает для свойства объекта allNames, чей ключ name, например. 'Alice'. Таким образом, например, когда впервые появляется имя Алисы, создается свойство с ключом Alice и ему присваивается значение 1. Это продолжается через исходный вход, в конечном итоге создавая конечный результат, который вы укажете.

0

Array.prototype.reduce() - это функция аккумулятора - она ​​будет перебирать все элементы в массиве и выполнять некоторую работу над ними, чтобы уменьшить их до одного значения. В этом примере мы инициализируем наше единственное значение как пустой объект, allnames = {}. По мере того, как мы итерируем имена, мы проверяем, существует ли это имя в объекте в качестве ключа - если это так, то мы увеличиваем счетчик, если это не так, мы инициализируем эту пару значений ключа <name>: 1:

var names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice']; 
var countedNames = names.reduce(function(allNames, name) { 
    if (name in allNames) { //first time through, allNames = {} 
    allNames[name]++; //if name is present as key in allNames object, increment the value by 1 
    } else { 
    allNames[name] = 1; //first time through now allNames = {'Alice': 1 } 
    } 

    return allNames; 
}, {}); //initialize allNames with empty object