Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> [SF][SF2][Symfony2] Co tu jest nie tak ?, jak zoptymalizować ten kawałek kodu ?
damianooo
post
Post #1





Grupa: Zarejestrowani
Postów: 496
Pomógł: 2
Dołączył: 15.07.2011
Skąd: Katowice

Ostrzeżenie: (0%)
-----


Chciałem się zapytać czy dobrze rozwiązałem poniższy problem:

Mam takie encje:

  1. users {id}
  2. matchdays {id}
  3. matches {id,matchday_id}
  4. points {id,user_id,match_id,numberOfpoints}


Potrzebuję pobrać dane tak aby wyświetlić dla każdego użytkownika sumy punktów dla każdej osobnej kolejki plus na końcu sumę wszystkich punktów ze wszystkich kolejek , tak aby później wyświetlić to w widoku TWIG, coś w tym stylu:

Imie /k1 /k2 /k3 /k4 /k5 / suma
---------------------------------
User3 / 4 / 2 / 4 / 2 / 4 / 16
User1 / 2 / 0 / 4 / 4 / 2 / 12
User2 / 2 / 0 / 2 / 4 / 2 / 1

Zrobiłem to tak:

  1. namespace My\TyperkaBundle\Repository;
  2. use Doctrine\ORM\EntityRepository;
  3.  
  4. class TypeRepository extends EntityRepository {
  5.  
  6. private $sum_per_user = array();
  7. private $users = array();
  8. private $final_result = array();
  9.  
  10. public function getPointsPerMatchday(){
  11.  
  12. $qb = $this->createQueryBuilder('t');
  13. $qb->select(
  14. 'SUM(t.numberOfPoints) AS suma'
  15. ,'u.username AS username'
  16. ,'u.id AS user'
  17. ,'u.priority'
  18. ,'md.id as matchday'
  19. )
  20. ->innerJoin('t.match', 'm')
  21. ->innerJoin('m.matchday', 'md')
  22. ->innerJoin('t.user', 'u')
  23. ->where('md.id BETWEEN 1 AND 15')
  24. ->groupBy('u.username, md.id')
  25. ;
  26.  
  27. $result = $qb->getQuery()->getResult();
  28.  
  29. // 1. Pobranie tylko użytkowników
  30. foreach ($result as $details){
  31. $this->users[] = $details['user'];
  32. }
  33.  
  34. // 2. Wybranie unikalnych wartości
  35. $this->users = array_unique($this->users);
  36.  
  37. // 3. Uporządkowanie kluczy
  38. $keys = array(0,1,2,3,4,5,6,7,8,9);
  39. $this->users = array_combine($keys, $this->users);
  40.  
  41. // 4. Zsumowanie punktów dla każdego użytkownika
  42. for($i=0;$i<10;$i++){
  43. foreach ($result as $details){
  44. if($this->users[$i] == $details['user']){
  45. if(!isset($this->sum_per_user[$this->users[$i]])){
  46. $this->sum_per_user[$this->users[$i]] = 0;
  47. }
  48. $this->sum_per_user[$this->users[$i]] = $this->sum_per_user[$this->users[$i]] + (int)$details['suma'];
  49. }
  50. }
  51. }
  52.  
  53. // 5. Posortowanie użytkowników wg sumy punktów
  54. arsort($this->sum_per_user);
  55.  
  56. // 6. Kolejne uporządkowanie kluczy
  57. $this->users = array_combine($keys, array_keys($this->sum_per_user));
  58.  
  59. // 7. Uporządkowanie danych użytkowników wg sumy punktów ze wszystkich kolejek
  60. // oraz zmiana wyglądu tablicy na: dla każdego użytkownika sumy punktów w każdej kolejce
  61. foreach($this->users as $user){
  62. foreach ($result as $details){
  63. if($user == $details['user']){
  64. if(isset($user)){
  65. $this->final_result[$details['username']][] = (int)$details['suma'];
  66. }
  67. }
  68. }
  69. }
  70.  
  71. return $this->final_result;
  72. }



Proszę o uwagi. Co zrobiłem źle ? Jak można to inaczej (może prościej) napisać ?
Będę wdzięczny za poprawki do kodu.

Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi
damianooo
post
Post #2





Grupa: Zarejestrowani
Postów: 496
Pomógł: 2
Dołączył: 15.07.2011
Skąd: Katowice

Ostrzeżenie: (0%)
-----


trochę mnie natchnąłeś ... i udało się fajnie zoptymalizować:

Podsumujmy:

// z SQLa miałem taką tablicę:
  1. $result = array(
  2. 0 => array("suma" => "26","username" => "Adam 1","user" => 9,"priority" => 1,"matchday" => 1),
  3. 1 => array("suma" => "23","username" => "Adam 1","user" => 9,"priority" => 1,"matchday" => 2),
  4. 2 => array("suma" => "20","username" => "Adam 1","user" => 9,"priority" => 1,"matchday" => 3),
  5. 3 => array("suma" => "18","username" => "Adam 1","user" => 9,"priority" => 1,"matchday" => 4),
  6. 4 => array("suma" => "14","username" => "Damian","user" => 12,"priority" => 2,"matchday" => 1),
  7. 5 => array("suma" => "22","username" => "Damian","user" => 12,"priority" => 2,"matchday" => 2),
  8. itd ...
  9. );


// 1. Sumuję więc łącznie wszystkie punkty ze wszystkich kolejek dla każdego usera
  1. foreach($result as $details){
  2. if(!isset($this->users[$details['user']])){
  3. $this->users[$details['user']] =0;
  4. }
  5. $this->users[$details['user']] = $this->users[$details['user']] + (int)$details['suma'];
  6. }


// otrzymuję to:
  1. $users = array(
  2. 9 => 87,
  3. 12 => 86,
  4. 2 => 90,
  5. 3 => 88,
  6. itd...
  7. );


// 2. Sortuję aby wiedzieć kto ma najwięcej punktów
  1. arsort($this->users);


// otrzymuję to:
  1. $users = array(
  2. 5 => 104,
  3. 16 => 102,
  4. 18 => 94,
  5. 13 => 92,
  6. 2 => 90,
  7. itd...
  8. );


// 3. Przypisuję punkty dla każdej kolejki osobno dla posortowanych już userów
// według łącznej sumy wszystkich punktów ze wszystkich kolejek
  1. foreach($this->users as $key => $value){
  2. foreach ($result as $details){
  3. if($key == $details['user']){
  4. $this->final_result[$details['username']][] = (int)$details['suma'];
  5. }
  6. }
  7. }


// i otrzymuję to co chcę a więc to:
  1. $final_result = array(
  2. "Mateusz" => array(24,26,28,26),
  3. "Tomek" => array(26,24,26,26),
  4. "Wojtek" => array(28,22,22,22),
  5. itd ...
  6. );



można to jeszcze zoptymalizować albo zrobić lepiej ?

Ten post edytował damianooo 26.01.2016, 20:54:20
Go to the top of the page
+Quote Post

Posty w temacie


Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 14.10.2025 - 17:42