动态生成json属性值

Dynamically generating json property value

本文关键字:属性 json 动态      更新时间:2023-09-26

我有一个json对象,如下所示:

{
    "critiquesAvg": 4.75: , 
    "critiques":[
        {
            'author': 'John Does',
            'comment': "I like it",
            'stars' : 5
        },
        {
            'author': 'Jacob Works',
            'comment': "I like it too",
            'stars' : 4.5
        }
    ]
}

我需要通过对临界数组的stars属性值进行平均来动态计算critiquesAvg的值(4.75)。

有人能帮我吗?

编辑:抱歉,我遇到的实际问题如下:

var dealers = [{
    "id", 1874
    "critiquesAvg": 4.75 ,
    "critiques":[
        {
            'author': 'John Does',
            'comment': "I like it",
            'stars' : 5
        },
        {
            'author': 'Jacob Works',
            'comment': "I like it too",
            'stars' : 4.5
        }
    ]
},
{
    "id": 1345,
    "critiquesAvg": 5 ,
    "critiques":[
        {
            'author': 'John Does',
            'comment': "I like it",
            'stars' : 5
        },
        {
            'author': 'Jacob Works',
            'comment': "I like it too",
            'stars' : 5
        }
    ]
}
];

在这里,我想根据特定经销商数据的临界值的平均值来动态计算CCD_ 3属性的值。

我会使用reduce(此处为fiddle):

var data = {
    "critiquesAvg": 4.75, 
    "critiques":[
        {
            'author': 'John Does',
            'comment': "I like it",
            'stars' : 5
        },
        {
            'author': 'Jacob Works',
            'comment': "I like it too",
            'stars' : 4.5
        }
    ]
};
var sum = data.critiques.reduce(function(x, y) { return x.stars + y.stars });
var average = sum / data.critiques.length;
data.critiquesAvg = average;
<小时>

对于更新后的问题,您需要添加一个额外的循环,例如使用forEach(此处为更新后的fiddle):

dealers.forEach(function(data) {
    var sum = data.critiques.reduce(function(x, y) { return x.stars + y.stars });
    var average = sum / data.critiques.length;
    data.critiquesAvg = average;
});

您可以通过将criticalsAvg替换为以下函数来实现这一点:

critiquesAvg: function(){
    var stars = 0;
    for(i=0;i<this.critiques.length;i++) {
        stars +=this.critiques[i].stars;
    }
    return stars/this.critiques.length
}, 

检查script.js这个plunker:http://plnkr.co/edit/dDxkZxKxvq0HRppASnzR?p=preview

向对象添加一个init函数,并在其中进行所有计算。如果你看看其他面向对象的语言,通常你会在构造函数中进行这种计算。同样,你可以用一个自定义方法来实现同样的计算,它将充当构造函数,并设置对象的初始状态

var obj = ({
  "critiquesAvg": 0, //start with zero and init function will calculate the actual avg
  "critiques": [{
    'author': 'John Does',
    'comment': "I like it",
    'stars': 5
  }, {
    'author': 'Jacob Works',
    'comment': "I like it too",
    'stars': 4.5
  }],
  init: function() {
    var result = this.critiques.reduce(function(prev, current, idx, arr) {
      return prev['stars'] + current['stars'];
    });
    this.critiquesAvg = result / this.critiques.length;
    return this;
  }
}).init(); // you are invoking the init method inline here (coding pattern)
           // also watch out for the ( ) around the object literal. 
           // this is what makes the method on the object invokable inline.

这是一种编码模式,通常用于设置对象状态(尤其是在javascript中使用对象文字语法时)。

演示

更新的答案

遵循相同的模式,但不是每个方法都有一个init方法,而是一个通用的initialize方法可以执行相同的操作。

var initialize = function() {
  var result = this.critiques.reduce(function(prev, current, idx, arr) {
    return prev['stars'] + current['stars'];
  });
  this.critiquesAvg = result / this.critiques.length;
  return this;
};
var dealers = [({
  "id": 1874,
  "critiquesAvg": 0,
  "critiques": [{
    'author': 'John Does',
    'comment': "I like it",
    'stars': 5
  }, {
    'author': 'Jacob Works',
    'comment': "I like it too",
    'stars': 4.5
  }],
  init: initialize
}).init(), ({
  "id": 1345,
  "critiquesAvg": 0,
  "critiques": [{
    'author': 'John Does',
    'comment': "I like it",
    'stars': 5
  }, {
    'author': 'Jacob Works',
    'comment': "I like it too",
    'stars': 5
  }],
  init: initialize
}).init()];

演示

Robby做到了,我想我会把它扩展到一个函数

function dataGen(data){
    //so we do not overwrite data globally as objects are references
    var data = data;
    var sum = data.critiques.reduce(function(x, y) {
        return x.stars + y.stars 
    });
    var average = sum / data.critiques.length;
    data.critiquesAvg = average;
    return data;
}
var data = { 
    "critiques":[
        {
            'author': 'John Does',
            'comment': "I like it",
            'stars' : 5
        },
        {
            'author': 'Jacob Works',
            'comment': "I like it too",
            'stars' : 4.5
        }
    ]
};
data.critiques.push({
    'author': 'Wacob Works',
    'comment': "I like it too",
    'stars' : 3.5
});
data = dataGen(data);

很好,根据您的要求进行了更新,希望这能有所帮助http://jsbin.com/sevor/1/edit

var dealers = [{
  "id": 1874,
    "critiquesAvg": 0 ,
    "critiques":[
        {
            'author': 'John Does',
            'comment': "I like it",
            'stars' : 5
        },
        {
            'author': 'Jacob Works',
            'comment': "I like it too",
            'stars' : 4.5
        }
    ]
},
{
    "id": 1345,
    "critiquesAvg": 5 ,
    "critiques":[
        {
            'author': 'John Does',
            'comment': "I like it",
            'stars' : 5
        },
        {
            'author': 'Jacob Works',
            'comment': "I like it too",
            'stars' : 5
        }
    ]
}
];
var Dealers = {
    calculate: function(dealer){
        var sum = dealer.critiques.reduce(function(x, y) {
            return x.stars + y.stars; 
        });
        var average = sum / dealer.critiques.length;
        return average;
    },
    gen: function(dealers){
        for(i=0;i<dealers.length;i++){
            dealers[i].critiquesAvg = this.calculate(dealers[i]);
        }
        return dealers;
    }
};
dealers = Dealers.gen(dealers);
dealers.push({
    "id": 1346,
    "critiquesAvg": 0 ,
    "critiques":[
        {
            'author': 'John Does',
            'comment': "I like it",
            'stars' : 5
        },
        {
            'author': 'Jacob Works',
            'comment': "I like it too",
            'stars' : 5
        }
    ]
});
dealers = Dealers.gen(dealers);
console.log(dealers);