ранжирование / позиция на многомерном массиве

у меня есть такой массив:

    Array
(
[1] => Array
(
[0] => Array
(
[user_id] => 13162
[selling_points] => 110.2
[total_points] => 189.6
[contest_name] => Gold
[position_selling] => 0
[position_final] => 0
)

[1] => Array
(
[user_id] => 16712
[selling_points] => 80.4
[total_points] => 90.3
[contest_name] => Gold
[position_selling] => 0
[position_final] => 0
)
)

[2] => Array
(
[0] => Array
(
[user_id] => 24613
[selling_points] => 1400.72
[total_points] => 1978.29
[contest_name] => Silver
[position_selling] => 0
[position_final] => 0
)
[1] => Array
(
[user_id] => 41317
[selling_points] => 775.33
[total_points] => 847
[contest_name] => Silver
[position_selling] => 0
[position_final] => 0
)
[2] => Array
(
[user_id] => 41045
[selling_points] => 655.03
[total_points] => 1065
[contest_name] => Silver
[position_selling] => 0
[position_final] => 0
)
)
)

Я хотел бы назначить 2 вида позиций по значениям selling_points (position_selling) и total_points (position_final).

Результат должен быть примерно таким:

Array
(
[1] => Array
(
[0] => Array
(
[user_id] => 13162
[selling_points] => 110.2
[total_points] => 189.6
[contest_name] => Gold
[position_selling] => 1
[position_final] => 1
)

[1] => Array
(
[user_id] => 16712
[selling_points] => 80.4
[total_points] => 90.3
[contest_name] => Gold
[position_selling] => 2
[position_final] => 2
)
)

[2] => Array
(
[0] => Array
(
[user_id] => 24613
[selling_points] => 1400.72
[total_points] => 1978.29
[contest_name] => Silver
[position_selling] => 1
[position_final] => 1
)

[2] => Array
(
[user_id] => 41045
[selling_points] => 655.03
[total_points] => 1065
[contest_name] => Silver
[position_selling] => 3
[position_final] => 2
)

[3] => Array
(
[user_id] => 41317
[selling_points] => 775.33
[total_points] => 847
[contest_name] => Silver
[position_selling] => 2
[position_final] => 3
)
)
)

Я пытался использовать PHP-функции, такие как usort и array_multisort, но безуспешно … Кто-нибудь может мне помочь?

0

Решение

<?php
$data = getData();
$s1 = array();
foreach( $data as &$v ) {
$s1[] = &$v;
}
$s2 = $s1;
usort( $s1, compareBy('selling_points'));
usort( $s2, compareBy('total_points'));

markPosition($s1, 'position_selling');
markPosition($s2, 'position_final');

echo '$data=', var_export($data); echo ";\r\n\r\n";function markPosition(array $arr, $key) {
foreach( $arr as $v=>&$k ) {
$k[$key] = $v+1;
}
}

function compareBy($key) {
return function($a,$b) use($key) {
return $b[$key] - $a[$key];
};
}function getData() {
return [
[
'user_id' => 1,
'selling_points' => 1,
'total_points' => 1,
],
[
'user_id' => 2,
'selling_points' => 4,
'total_points' => 4,
],
[
'user_id' => 3,
'selling_points' => 3,
'total_points' => 5,
],
];
}

У меня нет времени, чтобы объяснить это прямо сейчас (напомни мне завтра, если хочешь объяснений). И / или подожди лучшего решения …. 😉
Я пропустил один уровень вложенности вашего массива (ов), но это должно быть тривиально.

увидеть http://docs.php.net/references
и не пытайтесь сделать это без функции markPosition (), иначе вы, вероятно, получите непредвиденное поведение из-за ссылок в цикле foreach ….

0

Другие решения

Как я вижу, @VlkerK уже дал вам почти тот же ответ, что и я.

$arr = [
[
['user_id' => 13162,
'selling_points' => 110.2,
'total_points' => 189.6,
'contest_name' => 'Gold',
'position_selling' => 0,
'position_final' => 0
],
['user_id' => 16712,
'selling_points' => 80.4,
'total_points' => 90.3,
'contest_name' => 'Gold',
'position_selling' => 0,
'position_final' => 0
]
],
[
['user_id' => 24613,
'selling_points' => 1400.72,
'total_points' => 1978.29,
'contest_name' => 'Silver',
'position_selling' => 0,
'position_final' => 0
],
['user_id' => 41317,
'selling_points' => 775.33,
'total_points' => 847,
'contest_name' => 'Silver',
'position_selling' => 0,
'position_final' => 0
],
['user_id' => 41045,
'selling_points' => 655.03,
'total_points' => 1065,
'contest_name' => 'Silver',
'position_selling' => 0,
'position_final' => 0
]
]
];

$newArr = array();

function cmp($a, $b)
{
if ($a['selling_points'] == $b['selling_points']) {
return 0;
}
return ($a['selling_points'] < $b['selling_points']) ? 1 : -1;
}

function cmpTotal($a, $b)
{
if ($a['total_points'] == $b['total_points']) {
return 0;
}
return ($a['total_points'] < $b['total_points']) ? 1 : -1;
}

foreach($arr as $contest) {

usort($contest,'cmp');
$byTotal = $contest;
usort($byTotal,'cmpTotal');
$iTotal=1;
foreach($byTotal as &$user) {
$i = array_search($user,$contest);
$user['position_selling'] = $i+1;
$user['position_final'] = $iTotal++;
}
$newArr[] = $byTotal;
}

print_r($newArr);
0

По вопросам рекламы [email protected]