Как получить общее количество данных по разным дочерним элементам из Firebase в Android - PullRequest
1 голос
/ 03 мая 2020

Есть несколько дат и данных (курс и масштаб) для каждой даты. Каждая дата и данные хранятся под уникальным ключом. Даты вставляются с помощью средства выбора даты.

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

Я хотел бы рассчитать общее количество шкал на основе курса ежемесячно. Для шкалы, если число равно 3, это означает 0,6. Если число 2, это означает 0,4. Если число 4, значит 0,8. Таким образом, для курса А общее количество составляет 1,2 (0,6 + 0,6). Для курса 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) {

        }
    });

В этом случае запрос выполняется с начальной даты месяца до конечной даты месяца. Логика c для отображения двух детей неверна. Я не думаю, что hashmap подходит для этого случая, потому что может быть несколько данных с одним и тем же курсом с одинаковым масштабом (например, есть два одинаковых данных, курс A с масштабом 3 или числом 0,6). Пожалуйста, помогите мне исправить мои логи c.

1 Ответ

1 голос
/ 03 мая 2020

То, как вы используете свою дату, не очень эффективно. Потому что это означало бы, что 2020-4-12 предшествует 2020-4-4. Я предлагаю

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

Теперь, как говорится, вы используете ArrayList без необходимости. В противоположность тому, что вы сказали, HashMap можно использовать здесь. Также hm.get(i) вернул бы Double, и я не знаю, почему вы сравниваете его со строкой, когда вы должны сравнивать масштаб строки. В любом случае, посмотрите на эту модификацию вашего тела l oop. Я надеюсь, что вы знаете parseDouble, который преобразует строку в ее двойной эквивалент.

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

Если у вас есть какие-либо сомнения, не стесняйтесь комментировать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...