Как отсортировать многомерный массив по двум значениям с помощью оператора космического корабля?

Я пытаюсь отсортировать многомерный массив с помощью оператора космического корабля.

<?php

$my_array = [

['name'=>'cool', 'volume'=> 2, 'page'=>1],
['name'=>'sonic', 'volume'=> 1, 'page'=>1],
['name'=>'tails', 'volume'=> 3, 'page'=>1],
['name'=>'knuckles', 'volume'=> 1, 'page'=>2],
['name'=>'amy', 'volume'=> 1, 'page'=>3],
['name'=>'charmy', 'volume'=> 0, 'page'=>1]

];

usort($my_array, function ($a, $b) {
return $a['page'] <=> $b['page'];
});

var_dump($my_array);

Я могу сделать только с одним значением для сравнения, однако, как сортировать с помощью два значения (объем и страница)?

1

Решение

Если usort() это необходимо, то вы можете сделать это так:

<?php

$my_array = [

['name'=>'cool', 'volume'=> 2, 'page'=>1],
['name'=>'cool', 'volume'=> 1, 'page'=>1],
['name'=>'cool', 'volume'=> 3, 'page'=>1],
['name'=>'cool', 'volume'=> 1, 'page'=>2],
['name'=>'cool', 'volume'=> 1, 'page'=>3],
['name'=>'cool', 'volume'=> 0, 'page'=>1]

];

usort($my_array, function ($a, $b) {
$return = $a['page'] <=> $b['page'];
return ( !$return ? $a['volume'] <=> $b['volume'] : $return );
});

var_dump($my_array);

Я не проверял это, и вы не предоставили образец желаемого результата, поэтому вам может потребоваться изменить его в соответствии с вашими потребностями.

https://www.the-art-of-web.com/php/sortarray/#section_3 есть много отличных сортировок.

0

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

Не ответ на ваш вопрос, но я обычно делаю несколько значений следующим образом:

array_multisort(array_column($my_array, 'page'),
array_column($my_array, 'volume'), SORT_DESC, $my_array);
0

<?php

$my_array = [

['name'=>'cool', 'volume'=> 2, 'page'=>1],
['name'=>'cool', 'volume'=> 1, 'page'=>1],
['name'=>'cool', 'volume'=> 3, 'page'=>1],
['name'=>'cool', 'volume'=> 1, 'page'=>2],
['name'=>'cool', 'volume'=> 1, 'page'=>3],
['name'=>'cool', 'volume'=> 0, 'page'=>1]

];

usort($my_array, function ($a, $b) {
$page = $a['page'] <=> $b['page'];
$volume = $a['volume'] <=> $b['volume'];
if(0 == $page){
return $volume;
}else{
return $page;
}
});

var_dump($my_array);
0

Интересный способ представить функциональное программирование —

# main.php

require 'comparison.php';

function sortByPage ($a, $b) {
return $a['page'] <=> $b['page'];
}

function sortByVolume ($a, $b) {
return $a['volume'] <=> $b['volume'];
}

// first sort by volume, then sort by page
usort($my_array, \comparison\concat (sortByVolume, sortByPage));

Выше concat может быть не сразу интуитивно понятным. Конечно, вы concatдве строки или два массива, и вы даже можете подумать о добавлении чисел, таких как 1 + 2, как concat (1, 2), Но как это выглядит concat две функции?

Когда ты concat две строки, результатом является строка. Когда ты concat два массива, результатом является массив. Когда ты concat две функции сравнения, результатом будет другая функция сравнения.

# comparison.php

namespace comparison;

require 'ordered.php';

function concat ($c1, $c2) {
return function ($a, $b) use ($c1, $c2) {
return \ordered\concat
( $c1 ($a, $b)
, $c2 ($a, $b)
);
};
}

Функция сравнения принимает два аргумента и должна возвращать приказал результат, (-1, 0 или 1). Но так же, как мы можем реализовать concat для функций сравнения мы также можем реализовать concat для упорядоченных результатов. Итак, мы проходим $a а также $b для каждой функции сравнения, $c1 а также $c1каждый из которых приводит к приказал значение. Окончательный результат concat из двух упорядоченных значений.

Так что же происходит, когда ты concat два приказал ценности? Вы получаете другое заказанное значение!

// ordered.php

namespace ordered;

function concat ($a, $b) {
return $a === 0 ? $b : $a;
}

Выше это все, что вам нужно для достижения желаемого результата, но некоторые решения могут показаться произвольными. Может быть, вы также чувствовали, что это было утомительно, чтобы определить sortByPage а также sortByVolume как отдельные функции. Может быть, вам нужна способность задний ход сортировать тоже, и это будет означать определение даже Больше функции. Или, может быть, вам нужно отсортировать, используя Больше чем две функции сортировки. Расширение нашего comparison а также ordered модули помогут.

ordered.php

PHP традиционно использует -1, 0 и 1 для кодирования упорядоченного результата. Мы можем быть более явными об этом в нашем модуле. Обратите внимание, что каждая функция проста, как и одна или две вещи.

namespace ordered;

const eq = 0;
const gt = 1;
const lt = -1;

function concat ($a, $b) {
return $a === eq ? $b : $a;
}

function sum ($os) {
return array_reduce ($os, '\ordered\concat', eq);
}

function reverse ($a) {
return $a * -1;
}

comparison.php

В этом модуле мы реализуем <=> как функция compare вместо оператора. Обратите внимание, мы также вернули заказанные lt, gt, или же eq вместо -1, 1 или 0. Это учитывает барьер абстракции и позволяет приказал модуль, чтобы изменить свое представление, не влияя на сравнение модуль. Еще раз подчеркнем, что каждая функция выполняет только одну или две вещи.

namespace comparison;

require 'ordered.php';

function compare ($a, $b) {
if ($a < $b)
return \ordered\lt; // respect abstraction barrier
if ($a > $b)
return \ordered\gt; // respect abstraction barrier
else
return \ordered\eq; // respect abstraction barrier
}

function concat ($c1, $c2) {
return function ($a, $b) use ($c1, $c2) {
return \ordered\concat // respect abstraction barrier
( $c1 ($a, $b)
, $c2 ($a, $b)
);
};
}

function sum ($cs) {
return array_reduce ($cs, '\comparison\concat', '\comparison\compare');
}

function reverse ($c) {
return function ($a, $b) use ($c) {
return \ordered\reverse ($c ($a, $b)); // respect abstraction barrier
};
}

function contramap ($f, $g) {
return function ($a, $b) use ($f, $g) {
return $f
( $g ($a)
, $g ($b)
);
};
}

Эти простые модули подходят практически для любой задачи сортировки.

1. Объедините любое количество сортировщиков

// possibly based on form submission data
$sorters =
[ 'sortByVolume'  // pre-defined function
, 'sortByPage'    // pre-defined function
, 'sortByName'    // pre-defined function
];

usort ($my_array, \comparison\sum ($sorters));

2. Обратная сортировка

usort ($my_array, \comparison\reverse ('sortByVolume'));

3. Анонимные сортировщики — не нужно определять sortByVolume, sortByPage, так далее.

function sortBy ($key) {
return \comparison\contramap
( '\comparison\compare'
, function ($x) use ($key) { return $x[$key]; }
);
}

usort
( $my_array
, \comparison\concat
( sortBy ('volume') // sorter created ad hoc
, sortBy ('page')   // same here
)
);

4. Возможность смешивать и сочетать эти эффекты и получать надежный результат — неоспоримое преимущество функционального программирования.

$sorters =
[ 'sortByVolume',            // pre-defined function
, sortBy ('page')            // anonymous sorter
, reverse (sortBy ('name'))  // reverse sorter
];

usort
( $my_array
, \comparison\sum ($sorters) // combine all sorters
);

В конце концов, мы не использовали оператор космического корабля <=> в наших модулях. Функциональное программирование — это программирование с использованием функций, поэтому такие вещи, как операторы, ключевые слова и операторы, избегают использования простых функций. Причина этого в том, что функции могут быть легко объединены с использованием композиции, тогда как операторы и операторы не всегда могут быть объединены.

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