PHP Сортировка массива массивов на основе другого определенного пользователем массива

Надеюсь, я не открываю повторяющийся вопрос, но я не видел, чтобы этот тип вопроса задавался, или ответы, которые я видел, не работали с моим набором данных (но я очень новичок в этом).

Я надеюсь отсортировать следующий набор данных (массив массивов) на основе другого массива строк.

Код выполняется, и он выполняет функцию generateHtml только для строк, которые существуют в массиве $ ntbooks, который разработан. Мне нужно решить, как выполнить пользовательскую сортировку, используя $ ntbooks в качестве порядка. Прямо сейчас, когда код выполняется, а содержимое анализируется из content.php, порядок, в котором данные вводятся в меню, — это порядок их отображения (сверху вниз массива) — я бы хотел отсортировать данные так что написано от Матфея, потом Марка, Луки и т. д.

Это образец моих данных, но в нем содержится более 250 массивов (контентов), и я бы хотел избежать реструктуризации или реорганизации моего набора данных. Когда все сказано и сделано, generateHTML должен начинаться с matthew, mark, luke и проходить по списку.

Заранее спасибо за вашу помощь!

Динамически генерируемое меню HTML (menu.php):

                    include('content.php');

$main = array();

foreach($articles as $article)
{
foreach(explode("; ", $article["verse"]) as $verseData)
{

$verse = explode(" ", $verseData);

$book = $verse[0];
$verse = explode(":", $verse[1]);
$chapter = $verse[0];

if(empty($main[$book]))
$main[$book] = array();

if(empty($main[$book][$chapter]))
$main[$book][$chapter] = array();

if(empty($main[$book][$chapter][$verse[1]]))
$main[$book][$chapter][$verse[1]] = array();

$main[$book][$chapter][$verse[1]] = array
(
"full" => $article["full"]
);
}
}

$ntbooks = array("Matthew", "Mark", "Luke", "John", "Acts", "Romans", "1Corinthians", "2Corinthians", "Galatians", "Ephesians", "Philippians", "Colossians", "1Thessalonians", "2Thessalonians", "1Timothy", "2Timothy", "Titus", "Philemon", "Hebrews", "James", "1Peter", "2Peter", "1John", "2John", "3John", "Jude", "Revelation");


foreach($main as $book => $data)
{

if (in_array($book, $ntbooks)) {

generateHtml($book, $data);

}

}

function generateHtml($book, $data)
{
echo "<!-- ". $book ." -->\n";
echo "<div class=\"submenu\">\n";
echo "<a href=\"#\">". $book ."</a>\n";
echo "<!-- Level 2 menu -->\n";
echo "<div>\n";
echo "<div>\n";

foreach($data as $chapter => $verses)
{
echo "<div class=\"submenu\">\n";
echo "<a href=\"#\"">Chapter ". $chapter ."</a>\n";
echo "<!-- Level 3 menu -->\n";
echo "<div>\n";
echo "<div>\n";

foreach($verses as $verse => $value)
{
echo "<a href=\"#\"">Verse ". $verse ."</a>\n";
}

echo "</div>\n";
echo "</div>\n";
echo "</div>\n";

}


}

PHP Array of Arrays (content.php):

$articles = array(

array(
'contentid' => '0',
'full' => 'Item1 by Artist Name1 (Matthew 4)',
'verse' => 'Matthew 4:18-22',
'commentary' => ''),

array(
'contentid' => '1',
'full' => 'Item2 by Artist Name2 (Luke 15)',
'verse' => 'Luke 15:11-14; Luke 15:20-21',
'commentary' => ''),

array(
'contentid' => '2',
'full' => 'Item3 by Artist Name3 (John 3)',
'verse' => 'John 3:1-9',
'commentary' => ''),

array(
'contentid' => '3',
'full' => 'Item4 by Artist Name4 (John 8)',
'verse' => 'John 8:1-15A',
'commentary' => ''),

array(
'contentid' => '4',
'full' => 'Item5 by Artist Name5 (Matthew 27; Luke 23; John 19)',
'verse' => 'Matthew 27:20-23A; Luke 23:20-25A; John 19:2-3A',
'commentary' => 'Here '));

1

Решение

Вам необходимо выполнить сортировку с помощью пользовательской функции сравнения, где сравниваемые значения будут ключами из ссылочного массива, которые соответствуют значениям из массива данных.

Так что если:

$order = ['Matthew', 'Mark', 'Luke'];

и ваш массив данных verse гарантированно будет одним из вышеуказанных значений (в вашем примере это не правда!) тогда вы могли бы сделать это с

$comparison = function($a, $b) use ($order) {
return array_search($a['verse'], $order) - array_search($b['verse'], $order);
};

usort($data, $comparison);

Тем не менее, это не так просто в вашем случае, потому что verse не так удобно, как это. Вам нужно будет каким-то образом извлечь из него ценность интереса, упражнение, которое я не буду пытаться решить, потому что слишком много неизвестных (например, как 'Matthew 27:20-23A; Luke 23:20-25A; John 19:2-3A' должен быть отсортирован?).

0

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

использование usort,

От: http://php.net/manual/en/function.usort.php

bool usort ( array &$array , callable $value_compare_func ),

По сути, вы вызываете usort с массивом, который вы хотите отсортировать, и функцией, которая указывает порядок сортировки (сравните два объекта и определите, какой из них «больше»).

Поскольку книга находится в стихотворном объекте, вы можете сделать что-то вроде этого:

function sortCompare($obj1, $obj2)
{
$book1 = explode($obj1['verse'])[0];
$book2 = explode($obj2['verse'])[0];
return indexOf($book1, $ntbooks) - indexOf($book2, $ntbooks);
}

В какой момент вы можете позвонить
usort($articles, "sortCompare");,

sortCompare функция выше может нуждаться в настройке, но это хорошее начало.

0

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