如何从JavaScript中的对象计算新数据 [英] how to calculate new data from objects in javascript

查看:62
本文介绍了如何从JavaScript中的对象计算新数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下数据:

[ {
  "names" : [ "a3","printed","black" ],
  "value" : 15
}, {
  "names" : [ "a3","copied","black" ],
  "value" : 87
}, {
  "names" : [ "a3","printed","color","full" ],
  "value" : 37
}, {
  "names" : [ "a3","copied","color","single" ],
  "value" : 0
}, {
  "names" : [ "a3","copied","color","full" ],
  "value" : 44
}, {
  "names" : [ "a3","scanned" ],
  "value" : 288
}, {
  "names" : [ "total" ],
  "value" : 242142
}, {
  "names" : [ "scanned" ],
  "value" : 67411
}, {
  "names" : [ "copied","black" ],
  "value" : 79997
}, {
  "names" : [ "copied","full","color" ],
  "value" : 809
}, {
  "names" : [ "copied","single","color" ],
  "value" : 0
}, {
  "names" : [ "printed","two","color" ],
  "value" : 0
}, {
  "names" : [ "printed","black" ],
  "value" : 120665
}, {
  "names" : [ "printed","full","color" ],
  "value" : 40657
} ]

我试图创建某种结构来组织数据,以便可以查看对象之间的关系并计算新对象. 基本上我想要的是能够计算丢失的数据. 例如,我知道这些关系:

I tried to create some structure to organize the data in a way I can see relations between objects and calculate new objects. basically what I want is to be able to calculate missing data. So for example I know these relations:

{
  "colors" : {
    "black" : "",
    "color" : [ "full", "two", "single" ]
  },
  "functions" : {
    "scanned" : "",
    "total" : [ "printed", "copied", "faxed" ]
  },
  "papers" : {
    "a3" : ""
  }
}

基于此,我想获得以下信息:

Based on this I would like to get the following:

{
    "a3" : 183,
    "color" : 41466,
    "black" : 200662,
    "copied" : 80806,
    "printed" : 161322
}

我通过考虑以下几点来知道这一点: 总计a3仅由打印,复印和传真功能组成,因此例如a3扫描值不在a3总计值的计算范围之内.

I know it by taking into consideration the following: a3 total is only composed of the functions printed, copied and faxed so for example the a3 scanned value is not inside that calculation for the value of a3 total.

但是我想不出如何使用JavaScript的想法. 有人能指出我正确的方向吗?

but I can't think of any idea how to do it using JavaScript. can anybody points me in the right direction?

推荐答案

基本上,该提议使用树作为所需值.

Basically this proposal uses a tree for the wanted values.

  1. names属性的正确分配生成排序模式.

  1. Generate a sort pattern for the right assignment of names property.

迭代给定数据

  1. 获取a.names的副本.
  2. 排序names.
  3. 测试relations.functions.total是否包含names的第一个元素,然后将'total'移至名称.
  4. 迭代names并基于元素构建对象.
  5. value分配给对象中的value属性.
  1. Get a copy of a.names.
  2. Sort names.
  3. Test if relations.functions.total contains the first element of names, then unshift 'total' to names.
  4. Iterate names and build an object based on the elements.
  5. Assign value to the value property in the object.

  • 仅计算result.total分支的所有缺失值.

  • Calculate all missing values only for result.total branch.

    1. 这也汇总了所需项目的所有单个属性.

  • function calculateValues(o) {
        return Object.keys(o).reduce(function (r, k) {
            var v;
            if (k === 'value') {
                return r;
            }
            v = calculateValues(o[k]);
            if (o[k].value === null) {
                o[k].value = v;
            }
            values[k] = (values[k] || 0) + o[k].value;
            return r + o[k].value;
        }, 0);
    }
    
    var data = [{ names: ["a3", "printed", "black"], value: 15 }, { names: ["a3", "copied", "black"], value: 87 }, { names: ["a3", "printed", "color", "full"], value: 37 }, { names: ["a3", "copied", "color", "single"], value: 0 }, { names: ["a3", "copied", "color", "full"], value: 44 }, { names: ["a3", "scanned"], value: 288 }, { names: ["total"], value: 242142 }, { names: ["scanned"], value: 67411 }, { names: ["copied", "black"], value: 79997 }, { names: ["copied", "full", "color"], value: 809 }, { names: ["copied", "single", "color"], value: 0 }, { names: ["printed", "two", "color"], value: 0 }, { names: ["printed", "black"], value: 120665 }, { names: ["printed", "full", "color"], value: 40657 }],
        relations = { colors: { "black": "", color: ["full", "two", "single"] }, functions: { scanned: "", total: ["printed", "copied", "faxed"] }, papers: { "a3": "" } },
        priorities = ['functions', 'colors', 'papers'], // as long as keys of objects are not ordered
        order = {},
        result = {},
        values = {},
        i = 0;
    
    priorities.forEach(function (p) {
        Object.keys(relations[p]).forEach(function (k) {
            order[k] = ++i;
            Array.isArray(relations[p][k]) && relations[p][k].forEach(function (a) {
                order[a] = ++i;
            });
        });
    });
    
    data.forEach(function (a) {
        var names = a.names.slice();
        names.sort(function (a, b) {
            return (order[a] || 0) - (order[b] || 0);
        });
        if (relations.functions.total.indexOf(names[0]) !== -1) {
            names.unshift('total');
        }
        names.reduce(function (o, k) {
            return o[k] = o[k] || { value: null };
        }, result).value = a.value;
    });
    
    calculateValues(result.total);
    // calculateCount(result.scanned); 
    
    console.log(values);
    console.log(result);

    .as-console-wrapper { max-height: 100% !important; top: 0; }

    这篇关于如何从JavaScript中的对象计算新数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆