在Javascript对象中保持未知项目的计数

时间:2017-01-07 13:25:25

标签: javascript object

我正在解析一个数据源,并希望在JS中填充一个对象,最终得到像这样的东西:

data = {
    "USA":
        {"NY":{"active":5,"inactive":2}},
        {"WA":{"active":16,"inactive":11}},
    "Canada":
        {"NY":{"active":5,"inactive":2}}
}

一开始我不知道我将获得数据的国家或州的数量。所以我这样开始:

var data = {}

然后尝试填充这样的数据:

data["USA"]["NY"]["active"] = data["USA"]["NY"]["active"]++;

但它不起作用。

4 个答案:

答案 0 :(得分:2)

您需要为对象的每个级别进行检查,如果未设置,则将对象设为默认值或数字为零。



var data = {};

data["USA"] = data["USA"] || {};
data["USA"]["NY"] = data["USA"]["NY"] || {};
data["USA"]["NY"]["active"] = data["USA"]["NY"]["active"] || 0;
data["USA"]["NY"]["active"]++;

console.log(data);




更好的方法是使用函数来检查和制作默认对象



function getValue(o, path) {
    return path.reduce(function (o, k) {
        return (o || {})[k];
    }, o);
}

function setValue(object, path, value) {
    var way = path.slice(),
        last = way.pop();

    way.reduce(function (r, a) {
        return r[a] = r[a] || {};
    }, object)[last] = value;
}

function increment(object, path, value) {
    setValue(data, path, (getValue(data, path) || 0 ) + (value || 1));
}

var data = {};
increment(data, ['USA', 'NY', 'active'], 1);

console.log(data);




答案 1 :(得分:1)

您无法动态创建对象属性。因此,您正在正确创建数据对象:

var data = {}

但下一行是错误的,因为:

data["USA"]当时未定义,因此您无法访问["NY"] undefined,这将引发异常。因此,您不仅需要初始化根data对象,还需要为该对象的每个属性初始化一个对象。

你可以按字面意思做到:

if(!data["USA"]) 
    data["USA"] = {};

或使用||运算符,如果它存在,将为data["USA"]分配相同的对象(因此基本上什么也不做),或者它将创建一个新对象:

data["USA"] = data["USA"] || {};

现在您需要为您不能访问的每个对象执行此逻辑。所以使用较短的语法:

data["USA"] = data["USA"] || {};
data["USA"]["NY"] = data["USA"]["NY"] || {};
data["USA"]["NY"]["active"] = data["USA"]["NY"]["active"] || 0; 

之后,您的对象结构已准备就绪,请记住++是一个返回数字的运算符,然后在该数字上添加一个。

所以:

data["USA"]["NY"]["active"] = data["USA"]["NY"]["active"]++;

不会改变号码,你必须这样做:

data["USA"]["NY"]["active"]++;

或:

data["USA"]["NY"]["active"] = data["USA"]["NY"]["active"]+1;

答案 2 :(得分:0)

data["USA"]["NY"]["active"] = data["USA"]["NY"]["active"]++;

你是:

  1. data["USA"]["NY"]["active"](即2)
  2. 的值
  3. 递增data["USA"]["NY"]["active"](现在为3)
  4. 将您拍摄的值(2)分配给data["USA"]["NY"]["active"](有效扭转上一步的影响)
  5. 如果要增加值,请执行以下操作:

    data["USA"]["NY"]["active"]++;
    

    ......只是那个,除了那个。

答案 3 :(得分:0)

您可以使用reduce()创建自己的函数,该函数可以将字符串作为嵌套对象键并构建该深层对象结构。



var data = {}

function add(str) {
  var arr = str.split('.')
  return arr.reduce(function(r, e, i) {
    return arr.length - 1 != i ? r[e] || (r[e] = {}) : r[e] = (r[e] || 0) + 1
  }, data)
}

add('USA.NY.active')
add('USA.NY.active')
add('USA.NY.inactive')
add('Canada.NY.active')
console.log(data)