#php #arrays #sorting #usort
#php #массивы #сортировка #usort
Вопрос:
Так что я не совсем уверен, подходит ли ему заголовок лучше всего, но вот как выглядит массив:
array (
[0] => array (
[category] => 'Value_1'
[date] => '01/01/2011'
[data] => 'A'
)
[1] => array (
[category] => 'Value_3'
[date] => '01/01/2000'
[data] => 'B'
)
[2] => array (
[category] => 'Value_2'
[date] => '01/01/2011'
[data] => 'D'
)
[3] => array (
[category] => 'Value_2'
[date] => '01/01/2010'
[data] => 'A'
)
[4] => array (
[category] => 'Value_2'
[date] => '01/01/2011'
[data] => 'C'
)
)
Я бы хотел, чтобы эти данные были отсортированы следующим образом:
- Сохраняйте порядок категорий
- В категориях порядок по дате DESC
- Если даты появляются несколько раз, упорядочивайте данные в алфавитном порядке по
Затем массив примеров будет отсортирован по array ([0], [1], [4], [2], [3])
, более конкретно:
array (
[0] => array (
[category] => 'Value_1'
[date] => '01/01/2011'
[data] => 'A'
)
[1] => array (
[category] => 'Value_3'
[date] => '01/01/2000'
[data] => 'B'
)
[2] => array (
[category] => 'Value_2'
[date] => '01/01/2011'
[data] => 'C'
)
[3] => array (
[category] => 'Value_2'
[date] => '01/01/2011'
[data] => 'D'
)
[4] => array (
[category] => 'Value_2'
[date] => '01/01/2010'
[data] => 'A'
)
)
Моя проблема в том, что я знаю, что мне понадобится usort
и / или array_multisort()
, но я не совсем уверен, как эффективно выполнять итерацию по циклу для сортировки по заданным мной критериям.
Комментарии:
1. Можете ли вы показать нам желаемый результат массива выше?
2. Я пошел дальше и добавил некоторую ясность.
Ответ №1:
Ваша проблема может быть легко решена с помощью хорошей функции сравнения и uasort()
или usort()
. Вот как это работает:
Ваша функция сравнения принимает два параметра, которые являются элементами сортируемого массива. Верните -1, если первый параметр должен появиться первым в отсортированном массиве, верните 1, если второй параметр должен появиться первым, и верните 0, если оба параметра считаются равными в порядке сортировки.
Ваш критерий заказа такой: сортировка по категориям. Если категория одинакова, отсортируйте по дате. Если дата одинакова, отсортируйте по данным.
К сожалению, ваш массив неправильно структурирован. Что делать, если другая категория =Значение_3 отображается в качестве последнего элемента в массиве. Должен ли он быть сгруппирован с другими записями Value_3 или его следует сортировать отдельно? В зависимости от этого ответа массив следует реструктурировать для упрощения сортировки.
Другим улучшением является способ хранения даты. Формат даты America полностью непригоден для сортировки, ни как строка, ни как числовое значение. Либо преобразуйте его в временную метку unix, либо используйте формат даты ISO «ГГГГ-ММ-ДД». Оба можно легко сравнить без лишних слов.
Ответ №2:
Предположим, что ваш массив в $data
переменной, попробуйте это:
$data = Array(
0 => array(
"category" => 'Value_1',
"date" => '01/01/2011',
"data" => 'A'
),
1 => array(
"category" => 'Value_3',
"date" => '01/01/2000',
"data" => 'B'
),
2 => array(
"category" => 'Value_2',
"date" => '01/01/2011',
"data" => 'D'
),
3 => array(
"category" => 'Value_2',
"date" => '01/01/2010',
"data" => 'A'
),
4 => array(
"category" => 'Value_2',
"date" => '01/01/2011',
"data" => 'C'
)
);
$sorted = false;
foreach ($data as $index => $row) {
$data[$index]['date'] = strtotime($data[$index]['date']);
}
while (!$sorted) {
$aux = null;
$prevCat = null;
$prevDate = null;
$prevData = null;
foreach ($data as $index => $row) {
if ($prevCat != $row['category']) {
$prevCat = $row['category'];
$prevDate = $row['date'];
$prevData = $row['data'];
continue;
} else {
if ($row['date'] > $prevDate) {
$sorted = false;
$aux = $data[$index - 1];
$data[$index - 1] = $row;
$data[$index] = $aux;
break;
}
if ($row['date'] == $prevDate amp;amp; $row['data'] < $prevData) {
$sorted = false;
$aux = $data[$index - 1];
$data[$index - 1] = $row;
$data[$index] = $aux;
break;
}
$prevCat = $row['category'];
$prevDate = $row['date'];
$prevData = $row['data'];
}
}
$sorted = ($aux == null);
}
foreach ($data as $index => $row)
$data[$index]['date'] = date("m/d/Y", $data[$index]['date']);
var_dump($data);
// outputs
array(5) {
[0] => array(3) {
["category"] => string(7) "Value_1"
["date"] => string(10) "01/01/2011
["data"] => string(1) "A"
}
[1] => array(3) {
["category"] => string(7) "Value_3"
["date"] => string(10) "01/01/2000"
["data"] => string(1) "B"
}
[2] => array(3) {
["category"] => string(7) "Value_2"
["date"] => string(10) "01/01/2011"
["data"] => string(1) "C"
}
[3] => array(3) {
["category"] => string(7) "Value_2"
["date"] => string(10) "01/01/2011"
["data"] => string(1) "D"
}
[4] => array(3) {
["category"] => string(7) "Value_2"
["date"] => string(10) "01/01/2010"
["data"] => string(1) "A"
}
}
Комментарии:
1. я думаю, вам следует применить эту сортировку для каждого количества дат. Вы создаете массив, содержащий различные даты и сортировку по категориям, а затем данные. После этого объедините массивы по дате.
2. Это работает, и я принял ответ; однако, добавив ключ между 0 и 1 (перенумеровав их)
array ( "category" => 'Value_1', "date" => '01/02/2011', "data" => 'B')
, он больше не работает. Я попытаюсь разобраться.3. ops… Просто переместите
$prevDate
и другие внутри цикла! Посмотрите мой код сейчас4. Кроме того, вам необходимо добавить
amp;amp; $index > 0
к операторам if, которые могут быть выполнены при чтении данных, выходящих за пределы.5. @CharlesSmith, когда
$index == 0
then$prevData
и другие равны нулю, которые отличаются от$row['data']
и так далее…