2015-12-23 3 views
1

Я пытаюсь создать окончательный массив, который содержит суммированные числа объектов с месяцами и объединит те же месяцы и суммирует их itemCount.Не удается найти ошибку в моем JS-коде

Z массив из консоли Chrome:

0: Object 
itemCount: 6 
month: "Aug" 

1: Object 
itemCount: 0 
month: "Jun" 

2: Object 
itemCount: 0 
month: "Sep" 

3: Object 
itemCount: 0 
month: "Sep"  

и код, который я написал, чтобы подвести ITEMCOUNT месяцы и слияния, если есть одни и те же месяцы:

let counterCurrItem = 0, month, 
     finalArr = [], itemCount = 0 

    for (i = 0; i < Z.length; i++) { 
     month = Z[i].month 
     itemCount = Z[i].itemCount 
     if (Z[i + 1] !== undefined) { 
      if (month == Z[i + 1].month) { 
       counterCurrItem = counterCurrItem + itemCount 
      } else { 
       finalArr.push([counterCurrItem, month]) 
      } 
     } else { 
      finalArr.push([counterCurrItem, month]) 
     } 
    } 

Однако окончательный массив не удерживая ожидаемые значения, я ожидаю, что он будет иметь свой первый массив как [6, 'Aug], но это [0,' Aug '].

Итак, где проблема в моем коде?

Некоторые примечания: месяцы всегда сортируются в алфавитном порядке, а массив Z всегда содержит более одного объекта.

+3

вы пробовали использовать отладчик? –

+0

Можете ли вы опубликовать скрипку с результатом (с ошибкой) и ожидаемым результатом? – piotrwest

+1

Почему вы ожидаете этого результата? Я не смотрю на код. Что это значит, что 'counterCurrItem' будет' 6'? – Pointy

ответ

2

Вы добавляете такие предметы finalArr.push([counterCurrItem, month]), но переменная counterCurrItem добавлена ​​в инструкцию if, поэтому она никогда не увеличивается;

Кроме того, вы должны создать временную переменную в цикле, а не за ее пределами, чтобы не получить неверные данные.

Изготовление наименьшие изменения:

let counterCurrItem = 0, month, 
    finalArr = [], itemCount = 0 

for (i = 0; i < Z.length; i++) { 
    month = Z[i].month 
    itemCount = Z[i].itemCount 
    if (Z[i + 1] && month == Z[i + 1].month) { 
     counterCurrItem = counterCurrItem + itemCount 
     finalArr.push([counterCurrItem, month]) 
    } else { 
     finalArr.push([itemCount, month]) 
    } 
} 
1
if (month == Z[i + 1].month) { 
       counterCurrItem = counterCurrItem + itemCount 
      } else { 
       finalArr.push([counterCurrItem + itemCount, month]) <<<< 
      } 

Логическая проблема

1

Я думаю, что проблема в этом:

1)

if (month == Z[i + 1].month) 

Вы только сравнить текущий месяц элемента до e следующий. Вы должны сравнить его со всеми следующими элементами.

2) Вы определяете counterCurrItem в инструкции if-else. Определите его до if-else.

1

Альтернативное решение с использованием сокращений:

var monthMap = Z.reduce(function (acc, record) { 
     if (!acc[record.month]) acc[record.month] = 0; 
     acc[record.month] += record.itemCount; 
     return acc; 
    }, {}), 
    finalAry = Object.keys(monthMap).reduce(function (ary, key) { 
     ary.push([monthMap[key], key); 
     return ary; 
    }, []); 
+0

Спасибо, человек :) Мне нравится знать альтернативные решения. –

1

Хорошо так прочитать код до конца.

Он получает предмет 1 [6, авг].

month = Z[i].month //this is Aug 
itemCount = Z[i].itemCount // This is 6 

Z[i + 1] // This is not undefined 

month == Z[i + 1].month // Aug is not equal to Jun 

так называет:

finalArr.push([counterCurrItem, month]) // counterCurrItem is not defined so will become 0 

Надежда, что имеет смысл

1

Проблема заключается в том, что вы не установили counterCurrItem когда не два месяца подряд (например, в августе, например,), поэтому он будет читать 0, потому что это то, что было инициализировано.

// change this 
if (month == Z[i + 1].month) { 
    counterCurrItem = counterCurrItem + itemCount 
} else { 
    finalArr.push([counterCurrItem, month]) 
} 

// to this:   
if (month == Z[i + 1].month) { 
    counterCurrItem = counterCurrItem + itemCount 
} else { 
    finalArr.push([itemCount, month]); // changed!! 
}]) 
1

Я создал сценарий, который будет работать независимо от количества равных месяцев или сортировки.

Объяснение в комментариях к коду:

Z = [ 
    {itemCount: 1, month: 'Sep'}, 
    {itemCount: 6, month: 'Aug'}, 
    {itemCount: 0, month: 'Jun'}, 
    {itemCount: 2, month: 'Sep'} 
]; 

let counterCurrItem = 0, 
    month, 
    finalArr = [], 
    searchArr = [], // search array, will hold objects with their month as a key 
    itemCount = 0; 

// Loop over all elements in the original array 
Z.forEach(function(obj, i) { 
    // Get the current object's properties 
    month = obj.month; 
    itemCount = obj.itemCount; 

    // See if the current month has been added to the search array 
    if (searchArr[month] === undefined) { 
    // First time we see this month, so add it to the final array and the search array 
    finalArr.push(obj); 
    searchArr[month] = obj; 
    } 
    else { 
    // We had this month before, so loop over the final array, find the month, and update it's count 
    for (var j = 0; j < finalArr.length; j++) { 
     if (finalArr[j].month === month) { 
     finalArr[j].itemCount += itemCount; 
     } 
    } 
    } 
}); 

console.log(finalArr); 

Fiddle:https://jsfiddle.net/97y988m2/4/

Смежные вопросы