如何从FirebaseListObservable映射和减少子值 [英] How to map and reduce child values from FirebaseListObservable

查看:119
本文介绍了如何从FirebaseListObservable映射和减少子值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图总结测试分数,我的数据看起来像这样

  {testResult:
{foo :
{foo1:x},
{foo2:y}
},
{bar:
{bar1:z}
$ b $ f $和$ bar是问题的有意义的子类,子节点拥有问题ID和相应的分数。我需要总结按类别排列的分数。我查询这样的列表

  let res = this._dbref.database.list('/ bmzi-answers',{
查询:{
orderByKey:true,
equalTo:id
}
})

,并用 {{res | async | json}} 显示我,查询工作。我得到类似于

pre $ lt; code> [{cat1:3,cat2:3,cat3:3,$ key:cat}]

如何减少组件逻辑中的值所有问题的总和标记为猫*?



我理解像filter / map / reduce这样的概念,但是我是新来的Reactive Javascript,Angular2和AngularFire。



请帮助,并提前感谢您!

编辑:
所有孩子都有猫前缀,这是部分的域名/问卷。此代码

  let res = this.dbRef.database.list(`/ bmzi-answers / $ {id}`)$ ((array)=> {console.log(JSON.stringify(array));})
.map((array)=> array
.reduce((acc ,元素)=> acc + element。$ value,0)

let score = res.subscribe(sum => {
console.log(score:+ sum )
});
回报分数;

产生这个控制台输出,第一次被调用:

  [
{$ key:cat1,$ value:3},
{$ key:cat2 ,$ value:3},
{$ key:cat3,$ value:3}
]
得分:[object Object]

以及第二次:

 <$ 
$ {$$ value:3,$ key:fitges1}]
得分:undefined
[{ $ value:3,$ key:fitges1},{$ value:3,$ key:fitges2}]
score:undefined
[{$ value :3,$键 : fitges1 },{ $值 :3,$键 : fitges2 },{ $值 :3,$键 : fitges3\" }]
score:undefined


解决方案

以下数据:

  {
bmzi-answers:{
cat:{
cat1:3,
cat2:3,
cat3:3
}
}
}

您的查询使用 orderByKey equalTo 来获取列表observable发出一个数组。只要键存在,查询将只返回一个包含单个对象的数组。将查询路径中的键合并起来会更简单:

  let res = this._dbref.database.list (`/ bmzi-答案/ $ {ID}`); 

此查询返回的observable将是一个包含键的子元素的数组(以AngularFire方式表示) :
$ b

  [
{$ key:cat1,$ value:3},
{$ key:cat2,$ value:3},
{$ key:cat3,$ value:3}
]

可以使用RxJS map 运算符来转换发射阵列到另一个值,转换可以使用 Array.proptype 函数来执行,您声明您熟悉:

  let id =cat; 
让regExp = new RegExp(`$ {id} \\d +`);
let res = this._dbref.database
.list(`/ bmzi-answers / $ {id}`)
.map((array)=>数组
。 ((element)=> regExp.test(element.key))
.reduce((acc,element)=> acc + element。$ value,0)
);

如果所有的孩子都有 cat 过滤器不是必需的,但是您的问题没有说明是否是这种情况。


I am trying to sum up test scores, my data looks like this

   { testResult: 
      { foo:
         {foo1: x},
         {foo2: y}
      },
      { bar:
         {bar1: z}

'foo' and 'bar' are meaningful subcategories of questions, child-nodes hold questionIDs and corresponding scores. I need to sum up scores ordered by categories. I query the list like this

let res = this._dbref.database.list('/bmzi-answers',{
      query: {
        orderByKey: true,
        equalTo: id
      }
    })

and displaying the result with {{ res | async | json }} shows me, that the query works. I get something like

[{"cat1":3, "cat2":3, "cat3":3, "$key":"cat"}]

How can I reduce the values in my component logic, to get the sum of all questions labeled cat* ?

I understand concepts like filter / map / reduce, but I am new to Reactive Javascript, Angular2 and AngularFire.

Please help and thank you in advance!

Edit: All children have the cat prefix, this is part of the domain / the questionnaire. This code

  let res = this.dbRef.database.list(`/bmzi-answers/${id}`)
                  .do((array) => { console.log(JSON.stringify(array)); })
                  .map((array) => array
                      .reduce((acc, element) => acc + element.$value, 0)
            )
  let score = res.subscribe(sum => {
                  console.log("score: " + sum)
              });
  return score;

produces this console output, the first time it's called:

[
    { "$key": "cat1", "$value": 3 },
    { "$key": "cat2", "$value": 3 },
    { "$key": "cat3", "$value": 3 }
]
score: [object Object]

and the second time this:

[]  
score: undefined  
[{"$value":3,"$key":"fitges1"}]
score: undefined  
[{"$value":3,"$key":"fitges1"},{"$value":3,"$key":"fitges2"}]
score: undefined 
[{"$value":3,"$key":"fitges1"},{"$value":3,"$key":"fitges2"},{"$value":3,"$key":"fitges3"}]  
score: undefined 

解决方案

Your example output suggests the following data:

{
    "bmzi-answers": {
        "cat": {
            "cat1": 3,
            "cat2": 3,
            "cat3": 3
        }
    }
}

Your query uses orderByKey and equalTo to obtain a list observable that emits an array. Provided the key exists, the query will only ever return an array containing a single object. It would be simpler to incorporate the key in the query's path, like this:

let res = this._dbref.database.list(`/bmzi-answers/${id}`);

The observable returned by this query will be an array containing the key's children (represented in the AngularFire way):

[
    { "$key": "cat1", "$value": 3 },
    { "$key": "cat2", "$value": 3 },
    { "$key": "cat3", "$value": 3 }
]

The RxJS map operator can be used to transform the emitted array to another value and the transformation can be performed using the Array.proptype functions with which you state you are familiar:

let id = "cat";
let regExp = new RegExp(`${id}\\d+`);
let res = this._dbref.database
    .list(`/bmzi-answers/${id}`)
    .map((array) => array
        .filter((element) => regExp.test(element.$key))
        .reduce((acc, element) => acc + element.$value, 0)
    );

If all children have the cat prefix, the filter is not required, but your question doesn't make clear whether or not that's the case.

这篇关于如何从FirebaseListObservable映射和减少子值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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