如何从javascript中的对象计算新数据

Guy*_*ika 2 javascript arrays math json object

我有以下数据:

[ {
  "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
} ]
Run Code Online (Sandbox Code Playgroud)

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

{
  "colors" : {
    "black" : "",
    "color" : [ "full", "two", "single" ]
  },
  "functions" : {
    "scanned" : "",
    "total" : [ "printed", "copied", "faxed" ]
  },
  "papers" : {
    "a3" : ""
  }
}
Run Code Online (Sandbox Code Playgroud)

基于此,我想得到以下内容:

{
    "a3" : 183,
    "color" : 41466,
    "black" : 200662,
    "copied" : 80806,
    "printed" : 161322
}
Run Code Online (Sandbox Code Playgroud)

我知道它考虑到以下几点:a3总和仅由打印,复制和传真的功能组成,例如a3扫描值不在a3总值的计算范围内.

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

Nin*_*olz 23

基本上,此提议使用树来获取所需值.

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

  2. 迭代给定的数据

    1. 得到一份a.names.
    2. 排序names.
    3. 测试是否relations.functions.total包含第一个元素names,然后取消'total'名称.
    4. names基于元素迭代并构建对象.
    5. 分配valuevalue对象中的属性.
  3. 仅为result.total分支计算所有缺失值.

    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);
Run Code Online (Sandbox Code Playgroud)
.as-console-wrapper { max-height: 100% !important; top: 0; }
Run Code Online (Sandbox Code Playgroud)

  • 你真是太棒了!谢谢 (7认同)