简体   繁体   English

如何从 Android 中的 Firebase 中获取基于不同子项的总数据

[英]How to get total of data based on different child from Firebase in Android

There are multiples dates and data (Course and Scale) for each date.每个日期有多个日期和数据(课程和规模)。 Each date and data store under a unique key.每个日期和数据都存储在一个唯一的键下。 The dates are inserted by Date picker.日期由日期选择器插入。

"Data":{
   "K2ngvpioRUYF4bRM07Da5cbAjE53":{   //UID
      "-M3jNjCuGdMCwt1Czpwz":{        //unique key
         "Date":"2020-3-30",
         "Course":"A",
         "Scale":"3"
      },
      "-M5hxnQrCJdCUvRcMZJu":{
         "Date":"2020-4-24",
         "Course":"A",
         "Scale":"3"
      }
      "-M3jQWxm7z0EQYgkVenX":{
         "Date":"2020-4-29",
         "Course":"B",
         "Scale":"4"
      },
      "-M5hxn-rCJICUvRcMZJu":{
         "Date":"2020-4-24",
         "Course":"B",
         "Scale":"2"
      }
   }
}

I would like to calculate the total number of scales based on Course monthly.我想根据每月的课程计算秤的总数。 For scale, if the number is 3, it means 0.6.对于比例,如果数字为 3,则表示 0.6。 If the number is 2, it means 0.4.如果数字为 2,则表示 0.4。 If the number is 4, it means 0.8.如果数字是 4,则表示 0.8。 So, for the Course A, the total number is 1.2(0.6+0.6).因此,对于课程 A,总数为 1.2(0.6+0.6)。 For Course B, the total number is 1.2 (0.8+0.4).对于课程 B,总数为 1.2 (0.8+0.4)。

   Calendar mCalendar = Calendar.getInstance();
    int year = mCalendar.get(Calendar.YEAR);
    int month = mCalendar.get(Calendar.MONTH);
    final int[] Currmonth = {month + 1};         //this is array because there are other method using this but unnecessary for this question
    int lastDay = mCalendar.getActualMaximum(Calendar.DAY_OF_MONTH);
    int firstDay=1;
    String start=year+"-"+Currmonth[0]+"-"+firstDay;
    String end=year+"-"+Currmonth[0]+"-"+lastDay;
    DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("Users Mood");
    Query range = ref.child(user.getUid()).orderByChild("Date").startAt(start).endAt(end);
    range.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            ArrayList<String> courses=new ArrayList<>();
            Map<String, Double> hm = new HashMap<>();
            for(DataSnapshot ds : dataSnapshot.getChildren()) {
                String course=ds.child("Course").getValue(String.class);
                courses.add(course);
                String scale=ds.child("Scale").getValue(String.class);

                for(String i :courses) {
                    double num=0;
                    if (hm.get(i).equals("1")) {
                         num=0.2;
                    }else if(hm.get(i).equals("2")){
                         num=0.4;
                    }else if(hm.get(i).equals("3")){
                         num=0.6;
                    }else if(hm.get(i).equals("4")){
                         num=0.8;
                    }else if(hm.get(i).equals("5")){
                         num=1;
                    }
                    double total = hm.containsKey(course) ? hm.get(course) : 0;
                    total += num;
                    hm.put(course, total);
                }
           }
            for(String key:hm.keySet()) {
                Log.d("tag", key+hm.get(key));
            }

        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {

        }
    });

In this case, the query is from the start date of month to end date of the month.在这种情况下,查询是从月的开始日期到月的结束日期。 The logic for mapping two children is incorrect.映射两个孩子的逻辑是不正确的。 I don't think hashmap is suitable for this case because there might be few data with the same course with same scale (For example, there are two same data, Course A with scale 3 or num 0.6).我认为 hashmap 不适合这种情况,因为相同课程的相同比例的数据可能很少(例如,有两个相同的数据,课程 A 比例为 3 或 num 0.6)。 Please help me to correct my logic.请帮助我纠正我的逻辑。

The way you are using your date is not very efficient.您使用日期的方式不是很有效。 Because that would mean 2020-4-12 comes before 2020-4-4 .因为这意味着2020-4-122020-4-4之前。 I suggest我建议

//year is integer year
String monthStr = month; //month is integer month
if(month<=9)monthStr="0"+monthStr;
String dateStr = date; //date is integer date
if(date<=9)dateStr="0"+dateStr;
String finalStr = year+"-"+monthStr+"-"+dateStr;

Now that being said, You are using an ArrayList unnecessarily.话虽如此,您不必要地使用ArrayList On contrary to what you said the HashMap can be used here.与您所说的相反,此处可以使用 HashMap。 Also hm.get(i) would return Double and I dont know why you are comparing it to a string, when you should actually be comparing the string scale.另外hm.get(i)会返回 Double ,我不知道你为什么要将它与字符串进行比较,而实际上你应该比较字符串比例。 Anyway, Look at this modification I made to your loop body.不管怎样,看看我对你的循环体所做的修改。 I hope you know parseDouble which converts a String to its Double equivalent.我希望你知道parseDouble它将 String 转换为它的 Double 等价物。

for(DataSnapshot ds : dataSnapshot.getChildren()) {
            String course=ds.child("Course").getValue(String.class);
            String scale=ds.child("Scale").getValue(String.class);

                double num= Double.parseDouble(scale)/5.0;

                double total = hm.containsKey(course) ? hm.get(course) : 0;
                total += num;
                hm.put(course, total);

   }
   for(String key:hm.keySet()) {
        Log.d("tag", key+hm.get(key));
   }

If you have any doubts fell free to comment.如果您有任何疑问,请随时发表评论。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM