Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从javascript中的对象计算新数据_Javascript_Arrays_Json_Object_Math - Fatal编程技术网

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

如何从javascript中的对象计算新数据,javascript,arrays,json,object,math,Javascript,Arrays,Json,Object,Math,我有以下数据: [ { "names" : [ "a3","printed","black" ], "value" : 15 }, { "names" : [ "a3","copied","black" ], "value" : 87 }, { "names" : [ "a3","printed","color","full" ], "value" : 37 }, { "names" : [ "a3","copied","color","single" ], "v

我有以下数据:

[ {
  "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
} ]
我试图创建一些结构来组织数据,以便能够看到对象之间的关系并计算新对象。 基本上我想要的是能够计算丢失的数据。 例如,我知道这些关系:

{
  "colors" : {
    "black" : "",
    "color" : [ "full", "two", "single" ]
  },
  "functions" : {
    "scanned" : "",
    "total" : [ "printed", "copied", "faxed" ]
  },
  "papers" : {
    "a3" : ""
  }
}
基于此,我想得到以下信息:

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

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

但是我想不出如何使用JavaScript来实现它。
有人能给我指出正确的方向吗?

下面是概念的证明。是用咖啡脚本写的。您可以使用js2.coffee轻松地将其编译为JavaScript。除此之外,我还包括了JS代码以供参考。 不确定这是否是你要找的。这可能不是最好的方法,但它可能会帮助你。一旦你找到了,你可以设置你想要的第三种方式

###
这是下面的咖啡脚本
###
数组::containsAny=(arr)->
@一些(v)->
arr.indexOf(v)>=0
obj1=[]
obj2={}
obj3={}
totalArr=[]
colorArr=[]
bl=null
扫描=空
a3=零
对于obj2的k,v
如果k为“颜色”,则colObj=v
如果k是“函数”,则funcObj=v
paperObj=v,如果k为“papers”
如果colObj不为null
对于colObj的k,v
如果k为“颜色”,则colorArr=v
如果k‘黑色’,则bl=k
如果funcObj不为null
对于funcObj的k,v
如果k为“总计”,则totalArr=v
如果k被“扫描”,则扫描=k
如果paperObj不为空
对于paperObj的k,v
如果k为“a3”,则a3=k
返回
对于obj1的k,v
如果k为“名称”,则名称=v
如果k为“值”,则val=v
foundBlack=names.containsAny(['black'])
founda3=names.containsAny(['a3'])
foundColor=names.containsAny(colorArr)
foundTotal=names.containsAny(TotalArr)

返回
是否需要为每个
名称
计算
?如果是,请尝试

var output = {};
for (var i in data) {
    for (var j in data[i].names) {
        var mark = data[i].names[j];
        output[mark] = (output[mark] || 0) + data[i].value;
    }
} 

基本上,该方案使用一个树来表示所需的值

  • 名称
    属性的右赋值生成排序模式

  • 迭代给定的数据

  • 获取
    a.names
    的副本
  • 排序
    名称
  • 测试
    relations.functions.total
    是否包含
    names
    的第一个元素,然后将
    'total'
    反移位到names
  • 迭代
    名称
    并基于元素构建对象
  • value
    指定给对象中的
    value
    属性
  • 仅计算
    结果的所有缺失值。总计
    分支

  • 这将对所需项目的所有单个属性进行求和
  • 函数计算值(o){
    返回Object.keys(o).reduce(函数(r,k){
    var v;
    如果(k==‘值’){
    返回r;
    }
    v=计算值(o[k]);
    if(o[k]。值===null){
    o[k]。值=v;
    }
    值[k]=(值[k]| 0)+o[k]。值;
    返回r+o[k]。值;
    }, 0);
    }
    变量数据=[{名称:[“a3”,“打印”,“黑色”],值:15},{名称:[“a3”,“复制”,“黑色”],值:87},{名称:[“a3”,“打印”,“颜色”,“完整”],值:37},{名称:[“a3”,“复制”,“颜色”,“单一”],值:0},{名称:[“a3”,“复制”,“颜色”,“完整”],值:44},{名称:[“a3”,“扫描”],值:288},{名称:[“总计”],值:242142},{名称:[“已扫描”],{值:67411},{名称:[“已复制”,“黑色”],值:79997},{名称:[“已复制”,“完整”,“颜色”],值:809},{名称:[“已复制”,“单一”,“颜色”],值:0},{名称:[“已打印”,“两个”,“颜色”],值:0},{名称:[“已打印”,“黑色”],值:120665},{名称:[“已打印”,“完整”,“颜色”],值:40657}],
    关系={colors:{“black”:“”,color:[“full”,“two”,“single”]},函数:{scanned:,总计:[“printed”,“copied”,“faxed”]},纸张:{“a3”:“},
    优先级=[“函数”、“颜色”、“纸张”],//只要对象的键没有排序
    顺序={},
    结果={},
    值={},
    i=0;
    优先事项。forEach(职能(p){
    Object.key(关系[p]).forEach(函数(k){
    顺序[k]=++i;
    isArray(关系[p][k])&&relations[p][k].forEach(函数(a){
    顺序[a]=++i;
    });
    });
    });
    data.forEach(函数(a){
    var name=a.names.slice();
    名称.排序(函数(a,b){
    退货(订单[a]| | 0)-(订单[b]| | 0);
    });
    if(relations.functions.total.indexOf(names[0])!=-1){
    名称。取消移位(“总计”);
    }
    name.reduce(函数(o,k){
    返回o[k]=o[k]|{value:null};
    },结果)。值=a.值;
    });
    计算值(结果总数);
    //计算计数(结果扫描);
    console.log(值);
    控制台日志(结果)
    
    .as console wrapper{max height:100%!important;top:0;}
    您需要使用上述两个对象还是重构第三个对象就可以了?我必须继续使用问题顶部的对象数组。除此之外,其他一切都是可以改变的。我不太清楚你需要什么。。。您如何生成所需输出的数字?甚至不知道“关系”数据是如何用于生成所需输出的基于您所说的内容,您可能会研究类似于数组上的
    reduce()
    函数的内容。允许您将数据转换为完全不同的内容。你的累加器将只是一个包含你想要的键的散列。我知道这是考虑到以下几点:a3 total只由打印的函数组成,复制和传真,例如a3扫描值不在a3总计值的计算范围内。这是一个良好的开端,但并非每个名称的每个值都需要包含在计算范围内。我知道我的问题非常不清楚,所以我非常喜欢你开始计算的方式,并保持g