NodeJS-JSON数组推送元素,但不会增加长度

时间:2019-09-17 12:34:27

标签: javascript arrays node.js json

我正在NodeJS中创建一个JSON对象,该对象将在GET调用中返回。该对象必须从当日起每天返回3个小时的天气预报。

所需的JSON结构为:

所需的回复

{
    "current": {
        // Stuff... This part works fine
    },
    "forecast": [
        "Tuesday": [
            {
                // More stuff...
            },
            {
                // More stuff...
            },
            // More stuff...
        ],
        "Wednesday": [
            {
                // More stuff...
            },
            {
                // More stuff...
            },
            // More stuff...
        ],
        // More stuff...
    ]
}

在NodeJS中,我这样做:

json.forecast = [];
json.forecast[weekDay] = [];

for (var i = 1; i < data.cnt; i++) {
  var hour = {};
  var forecastDay = getDay(forecast[i].dt_txt);

  if (forecastDay !== weekDay) {
    weekDay = forecastDay;
    json.forecast[weekDay] = [];
  }

  hour.date           = forecast[i].dt_txt || 'unknow';          
  hour.day            = getDay(forecast[i].dt_txt);                                    
  hour.time           = getTime(forecast[i].dt_txt);                                   
  hour.temp           = getValue(forecast[i].main.temp);                               
  hour.maxtemp        = getValue(forecast[i].main.temp_max);                           
  hour.mintemp        = getValue(forecast[i].main.temp_min);                           
  hour.wind_speed     = getValue(forecast[i].wind.speed);                              
  hour.rain           = forecast[i].rain ? forecast[i].rain["3h"] : 'unknow';          
  hour.humidity       = getValue(forecast[i].main.humidity);                           
  hour.condition      = {};                                                            
  hour.condition.text = forecast[i].weather[0].description || 'unknow';          
  hour.condition.icon = getIconUrl('openweather', forecast[i].weather[0].icon, logger);

  json.forecast[weekDay].push(hour);
}

var“ weekDay”是通用的,因为我不知道我将在哪一天开始,并且因为我想为运行时的每一天创建一个新项目。

问题在于每天都有物品推入数组,但长度没有增加:

NodeJS debug

GET响应返回一个空数组:

Postman response

4 个答案:

答案 0 :(得分:1)

您的预测是一个数组,但是数组是索引数据结构。在JS中,一切都是对象,因此您可以输入基于字符串的属性,但是对于基于索引的值,长度将增加。因此,您看到的长度为0。

以下是说明length的工作方式的示例。

  

长度=最后一个元素的索引+ 1

实际上,任何未索引的值都不会被迭代。

var data = [];

data['foo'] = 'Hello World';

console.log(data.length);

data[10000] = 0;

console.log(data.length);

data.forEach((value, index) => console.log(value, index))

答案 1 :(得分:1)

构建预测数组很麻烦。

"forecast": [
    "Tuesday": [
        {
           // More stuff...

应该改为

"forecast": [
        {
           "day": "Tuesday",
           // More stuff...

或(不理想)

"forecast": { 
    "Tuesday": [
        {
           // More stuff...

这是不理想的,因为通常用诸如“星期二”之类的任意值来命名对象键是不正确的做法。

答案 2 :(得分:1)

好的,一些可能的答案:

尝试为.push()中的元素添加另一个forecast,而不指定weekDay。在我看来,您要在数组中添加一个不同于数字的索引(错误地称为 string index ),并且它将数组转换为对象(长度为0)。您可以看看here类似的东西。

在JavaScript中,没有数组的原始类型。它是带有数字索引的对象。

//I said I want an array.
var arr = [];

// But it is an object, with some special proprieties.
console.log(typeof arr) // object

// It is an instance of the Array class. Notice the capitalized 'A' meaning the class.
console.log(arr instanceof Array) //true

// And the reason you know it is an object is that you can add attributes this way.
arr['foo'] = 'bar' 
arr['frodo'] = 'bagging'
arr['ramm'] = 'stein'

// Don't be fooled by [brackets], it is still an object. 
console.log(arr)  // [ foo: 'bar', frodo: 'bagging', ramm: 'stein' ]

// Only arrays have different props like length added by default.
console.log(arr.length) //0

您可以通过3种替代方法来解决此问题:

  • 您可以使用数组编号索引来分配值(而不是“星期六”,“星期一”字符串)。使用数组索引(例如:arr[0]访问第一个元素)。请记住,数组序列很重要,但原始对象序列并不重要。
[{
   data: {...} 
},{
   data: {...} 
}]
  • 您可以在每个主要对象中添加适当性nameweekDay
[{
   weekDay: 'Monday',
   hour: {...}
},{
   weekDay: 'Tuesday',
   hour: {...}
}]
  • 或者,您也可以使用名称来定义对象内部的其余属性。在现代Javascript中,您可以使用Object.keys(arr)Take a look)或for..inTake a look)之类的对象遍历对象。请记住,不能使用两个相同的对象键(两个Mondays)。
{
   'Monday': { ... },
   'Tuesday': { ... } 
}

答案 3 :(得分:0)

您需要启动 json.forecast = [];json.forecast = {};一样,因为它是一个对象而不是一个数组。

执行json.forecast[weekDay] = [];时,它会将weekDay属性添加到json.forecast中,但是最初定义的json.forecast数组中没有任何变化


使用对象的其他好处

  • 不需要循环:for (var i = 1; i < data.cnt; i++),因为您仅更新预测日的值
  • 不需要多次初始化json.forecast[weekDay] = [];,因为您可以一次初始化JSON并一次又一次更新值。
  • 无需其他检查if (forecastDay !== weekDay)
  •  --