Надеюсь, я не открываю повторяющийся вопрос, но я не видел, чтобы этот тип вопроса задавался, или ответы, которые я видел, не работали с моим набором данных (но я очень новичок в этом).
Я надеюсь отсортировать следующий набор данных (массив массивов) на основе другого массива строк.
Код выполняется, и он выполняет функцию 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 '));
Вам необходимо выполнить сортировку с помощью пользовательской функции сравнения, где сравниваемые значения будут ключами из ссылочного массива, которые соответствуют значениям из массива данных.
Так что если:
$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'
должен быть отсортирован?).
использование 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
функция выше может нуждаться в настройке, но это хорошее начало.