Странное поведение, толкающее массив, хранящийся в значении объекта JavaScript - PullRequest
0 голосов
/ 02 ноября 2018

Внутри предложения else закомментированная строка дает желаемый результат, но та, что ниже, заставляет {'1': [1.3], '2': [2.1]} стать {'1': [1.3 ], '2': 2}. Я не понимаю, почему это происходит.

const groupBy = (array, callback) => {
  let obj = {}
  for (let i = 0; i < array.length; i++) {
    let currKey = callback(array[i])
    let newVal = array[i]
    let currVal = obj[currKey]
    if (!currVal) {
        obj[currKey] = [newVal]
    } else {
        // obj[currKey].push(newVal)
        obj[currKey] = currVal.push(newVal)
    }
  } 
  return obj
} 

// Uncomment these to check your work!
var decimals = [1.3, 2.1, 2.4]
var floored = function(num) { return Math.floor(num) }
groupBy(decimals, floored); // expect { 1: [1.3], 2: [2.1, 2.4] }

1 Ответ

0 голосов
/ 02 ноября 2018

Array.prototype.push не возвращает новый массив, он возвращает длину массива.

const groupBy = (array, callback) => {
  // let arrayValues = [] // this isn't used anywhere
  let obj = {}
  for (let i = 0; i < array.length; i++) {
    let currKey = callback(array[i])
    let newVal = array[i]
    let currVal = obj[currKey]
    if (!currVal) {
        obj[currKey] = [newVal]
    } else {
        obj[currKey].push(newVal) // this should work instead
        //obj[currKey] = currVal.push(newVal)
    }
  } 
  return obj
}

Поскольку массивы являются ссылочным типом, вам просто нужно вставить новый элемент в массив obj[currKey].push(newValue) без повторной установки obj[currKey]. Вы помещаете новое значение в этот массив, где оно находится в памяти, поэтому нет необходимости переназначать его чему-либо. Вы можете увидеть, как lodash делает это здесь (хотя вам придется распутать некоторые вспомогательные функции).

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push

...