Объект JS, созданный с помощью for/in, возвращающий один и тот же объект в массив несколько раз

#javascript #arrays #object #for-in-loop

Вопрос:

У меня есть данные объекта, которые выглядят так:

 {
    "Meta Data": {
        "1. Information": "Intraday (5min) open, high, low, close prices and volume",
        "2. Symbol": "IBM",
        "3. Last Refreshed": "2021-09-09 18:05:00",
        "4. Interval": "5min",
        "5. Output Size": "Compact",
        "6. Time Zone": "US/Eastern"
    },
    "Time Series (5min)": {
        "2021-09-09 18:05:00": {
            "1. open": "137.8300",
            "2. high": "137.8300",
            "3. low": "137.8300",
            "4. close": "137.8300",
            "5. volume": "104"
        },
        "2021-09-09 17:25:00": {
            "1. open": "137.7500",
            "2. high": "137.7500",
            "3. low": "137.7500",
            "4. close": "137.7500",
            "5. volume": "478"
        },
        "2021-09-09 16:30:00": {
            "1. open": "137.8000",
            "2. high": "137.8000",
            "3. low": "137.8000",
            "4. close": "137.8000",
            "5. volume": "459"
        },
    }
}
 

Вот моя функция:

 const myfunction = () => {
  var newArray = []
  var newObject = {}
  var firstobj = myobject['Time Series (5min)']

  for (var key in firstobj) {
    console.log(key)
    newObject.x = key.substr(11, 19)
    newObject.y = myobject['Time Series (5min)'][`${key}`]['4. close']

    newArray.push(newObject)
  }
  return newArray
}

console.log(myfunction())
 

Объект JS, созданный с помощью for/in, возвращает один и тот же объект в массив несколько раз. Я не уверен, почему я не могу увидеть ошибку или где я ошибаюсь. Кто-нибудь знает, как я должен возвращать объект в newArray так, чтобы он создавал список {x: 1234, y: 1234} . (только примеры номеров, см. Изображение, прикрепленное к этому коду представления / консоли вместе. Первая часть консоли — это конец зарегистрированных ключей, а 2-я часть консоли-это начало журнала для массива объектов, [{x: 1234, y: 1234}, {x: 1234, y: 1234}] я хотел бы вернуться!

Результат должен быть:

 [{ x: '15:50:00', y: '138.3550' },
 { x: '15:55:00', y: '134.3250' }]
 

нет:

 [{ x: '15:50:00', y: '138.3550' },
 { x: '15:50:00', y: '138.3550' }]
 

PS: Я вернул структуру в виде массива, но не в виде массива объектов. Я просто хотел сказать, что я правильно вызываю API, просто, возможно, неправильно ссылаюсь на него.

PPS: Если есть гораздо более простой способ сделать это, пожалуйста, дайте мне знать, что бы вы сделали!

Ответ №1:

Вы нажимаете на newArray полную со ссылками на один и тот же объект.

 const obj = { x: 0, y: 0 };
const newArray = [obj];

obj.x = 1;
newArray.push(obj);

// since index 0 and 1 refer to the same object they will now "both" be
// { x: 1, y: 0 }
 

Поэтому вместо использования одного объекта создайте копию, а затем обновите свойства:

 for (var key in firstobj) {
  console.log(key)
  const copy = { ...newObject }; // create a shallow copy

  // Setting x and y don't update newObject, and objects pushed to
  // newArray are distinct objects.
  copy.x = key.substr(11, 19)
  copy.y = myobject['Time Series (5min)'][`${key}`]['4. close']

  newArray.push(copy)
}
 

Комментарии:

1. Большое спасибо! Это действительно помогло и смогло научить меня, где я ошибаюсь!

Ответ №2:

Вместо того, чтобы создавать новую переменную для временного хранения значения, вы можете просто поместить ее полностью в push саму себя, как это:

 array.push({x: data_x, y: data_y})
 

Вот полный рабочий код:

 const data = {
    "Meta Data": {
        "1. Information": "Intraday (5min) open, high, low, close prices and volume",
        "2. Symbol": "IBM",
        "3. Last Refreshed": "2021-09-09 18:05:00",
        "4. Interval": "5min",
        "5. Output Size": "Compact",
        "6. Time Zone": "US/Eastern"
    },
    "Time Series (5min)": {
        "2021-09-09 18:05:00": {
            "1. open": "137.8300",
            "2. high": "137.8300",
            "3. low": "137.8300",
            "4. close": "137.8300",
            "5. volume": "104"
        },
        "2021-09-09 17:25:00": {
            "1. open": "137.7500",
            "2. high": "137.7500",
            "3. low": "137.7500",
            "4. close": "137.7500",
            "5. volume": "478"
        },
        "2021-09-09 16:30:00": {
            "1. open": "137.8000",
            "2. high": "137.8000",
            "3. low": "137.8000",
            "4. close": "137.8000",
            "5. volume": "459"
        },
       }
      };



const myfunction = (myobject) => {
  var newArray = [];
  var firstobj = myobject['Time Series (5min)'];

  for (var key in firstobj) {
    console.log(key)

    newArray.push({
      x: key.substr(11, 19),
      y: myobject['Time Series (5min)'][`${key}`]['4. close']
    });
  }
  return newArray
}

console.log(myfunction(data)) 

Ответ №3:

Это связано с тем, что newObject обновляется каждый раз, когда он вызывает. Поэтому он сохраняет последнее значение в качестве переменной. Посмотрите на эту фотографию.

введите описание изображения здесь