0

Good time.

I have a multidimensional array $a like this:

$a[0] = [1,5,2022-04-01,2022-04-20, 5, 10:30:00, 11:30:00, 1, 700];
$a[1] = [1,5,2022-04-05,2022-04-15, '', 10:30:00, 11:30:00, 1, 800];
$a[2] = [1,0,2022-04-07,2022-04-15, '', '', '', 1, 800];
$a[3] = [1,5,2022-04-06,2022-04-16, '', '', '', 0, 900];
$a[4] = [1,5,2022-04-07,2022-04-12, '', '', '', 0, 600];
 ...
$a[n] = [1,0,2022-04-06,2022-04-16, 4, '', '', 0, 1100];

First four elements in each $a[] are always not-empty. Elements from 5 to 7, as you see, can be empty or not. Element 8 can be only 0 or 1, but not empty. And the last element is always not-empty.

I want to sort this multi-dimensional array with some "score" logic:

First rule:

  • if we have empty all 5, 6 and 7 elements (like we have in $a[2]) - the score of this $a[] is 1
  • if we have empty only 6 and 7 elements, and 5 is not-empty, (like we have in $a[n]) - the score of this $a[] is 2
  • if we have empty only 5 element, but 6 and 7 are not-empty (like we have in $a[1]) - the score of this $a[] is 3
  • if we have all 5, 6 and 7 elements not-empty (like we have in $a[0]) - the score of this $a[] is 4

Also second rule:

  • if score for two $a[] is the same, but 8th element is different, the sorting function have to put one of them with "1" as 8th parameter higher, than another

And last rule:

  • if two (or more) $a[] have the same score and and also 8th parameter is the same, the sorting function have to put higher those, that have less difference between 4 and 3 parameter (in fact it is a difference between 2 dates).

So, the result have to be from highest to lowest:

[1,5,2022-04-01,2022-04-20, 5, 10:30:00, 11:30:00, 1, 700]; // 4 scores 
[1,5,2022-04-05,2022-04-15, '', 10:30:00, 11:30:00, 1, 800]; //3 scores 
[1,0,2022-04-06,2022-04-16, 4, '', '', 0, 1100]; // 2 scores 
[1,0,2022-04-07,2022-04-15, '', '', '', 1, 800]; // 1 score + 8th parameter is "1" 
[1,5,2022-04-07,2022-04-12, '', '', '', 0, 600]; // 1 score + dates difference is 5 days 
[1,5,2022-04-06,2022-04-16, '', '', '', 0, 900]; // 1 score + dates difference is 10 days

How it can be done in php?

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • sorry for maybe not-good-looking formatting in my question, i hope that moderator will improve my formatting – Natalya GNS Apr 12 '22 at 17:11
  • Use `usort()` with a comparison function that calculates the scores for each parameter and compares them. – Barmar Apr 12 '22 at 17:15
  • Thanks for your reply. I found examples of simple comparison function for usort(), like this (in my case, it makes first elements those that have 5th element not-empty: `function cmp(array $a, array $b) { if ($a[4] > $b[4]) {//first will be with populated value return -1; } else if ($a[4] < $b[4]) { return 1; } else { return 0; } } usort($a, 'cmp'); var_dump($a); ` How can i add second rule in this cmp function? For example, if 5th and 6 th and 7th are not-empty, it have be upper in sorted array. Everywhere i find only simple examples – Natalya GNS Apr 12 '22 at 17:44
  • Write a function that calculates the score. Then you can use `function cmp($a, $b) { return score($a) - score($b); }`. – Barmar Apr 12 '22 at 17:48
  • It will be a little more complicated because of your last rule, but that's the general idea. – Barmar Apr 12 '22 at 17:48
  • yes, your last example with returning score($a) - score($b) seems to be good idea, thanks – Natalya GNS Apr 12 '22 at 17:51
  • So it works fine on php5.6 server, but does not work on php7 server. The sorting runs with `usort($recordsarr, 'cmp2');` and the cmp2 function is `function cmp2(array $a, array $b) { return (score($b) - score($a)); }`. On php7 server it shows me: "Usort() expects parameter 2 to be a valid callback". I also tried variant with `usort($recordsarr, function($a, $b) {cmp2($a, $b);});`, it does not show an error, but is not sorting - aray remains the same. What i have to fix to make it work on php7 server? – Natalya GNS Apr 13 '22 at 05:59
  • using `usort($recordsarr, array( $this, "cmp2" ));` fixed the problem – Natalya GNS Apr 13 '22 at 11:00
  • That would only be necessary if `cmp2` is a class method. If it's an ordinary function you don't need the array. – Barmar Apr 13 '22 at 14:55

0 Answers0