代码之家  ›  专栏  ›  技术社区  ›  skip

动态生成json属性值

  •  1
  • skip  · 技术社区  · 10 年前

    我有一个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
            }
        ]
    }
    

    我需要计算 critiquesAvg 通过平均 stars critices数组的属性值。

    有人能帮我吗?

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

    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
            }
        ]
    }
    ];
    

    这里我想计算 临界值平均值 属性,基于特定经销商数据的评论平均数。

    4 回复  |  直到 10 年前
        1
  •  3
  •   Robby Cornelissen    10 年前

    我会用 reduce 为了这个(小提琴) here ):

    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 here ):

    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;
    });
    
        2
  •  2
  •   Jyoti Puri    10 年前

    您可以通过以下函数替换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这个插件: http://plnkr.co/edit/dDxkZxKxvq0HRppASnzR?p=preview

        3
  •  1
  •   Prabhu Murthy    10 年前

    向对象添加一个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中使用对象文本语法时)。

    DEMO

    更新的答案

    遵循相同的模式,但不是每个都有一个init方法,而是一个通用的初始化方法将执行相同的操作。

    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()];
    

    DEMO

        4
  •  1
  •   FlatLander    10 年前

    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);