how to calculate new data from objects in javascript how to calculate new data from objects in javascript json json

how to calculate new data from objects in javascript


Basically this proposal uses a tree for the wanted values.

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

  2. Iterate the given data

    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.
  3. Calculate all missing values only for result.total branch.

    1. This sums all single properties as well for the wanted items.

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