Вас назначили на проект нового китайского интернет-магазина "SuperDuperDeal.Com". В магазине лежит свыше 9000 товаров, отсортированных по категориям. Вас попросили написать страницу "Карта сайта" и вывести на ней все категории. Проблема в том, что список категорий очень большой и глубина его заранее неизвестна. В качестве исходных данных вам дан массив категорий в виде:
$cats = [
"Electronics" => [
"Phones" => ["Mobile Phones", "Satellite Phones"],
"Tablets",
...
],
...,
"Special Deals"
].
Ваша задача — обойти дерево и вывести его в том порядке, в котором оно вам дано, то есть:
Electronics
Phones
Mobile Phones
Satellite Phones
Tablets
...
...
Special Deals
Уважаемые учащиеся ниже Вы сможете увидеть ответ, перед тем, как ответить, пожалуйста, постарайтесь написать для себя ответ на черновике, и только потом сравните наш ответ с Вашим:
Верно ли наше решение?
Ответ:
Несмотря на простоту задачи, с её помощью можно много чего узнать о кандидате. Для начала, мы хотим узнать, понимает ли кандидат понятие рекурсии. Самым простым решением исходной задачи будет что-нибудь вроде этого:
function print_subtree_simple(array $subtree, $depth) {
foreach ($subtree as $key => $value) {
echo str_repeat(" ", $depth*2);
if (is_array($value)) {
echo "$key<br/>";
print_subtree_simple($value, $depth+1);
} else {
echo "$value<br/>";
}
}
}
print_subtree_simple($cats, 0);
Вывод, правда, у нас получился не очень красивый, без тэгов <nav> или хотя бы <ul> и <li>, но это и не требовалось. Зато здесь есть грабли с забыванием вывести категорию-предка (строка echo "$key<br/>;"). В остальном всё просто.
Правда, нам только что позвонил заказчик и напомнил, что заголовки категорий должны быть ссылками на соотвествующие страницы.
Ссылки на нашем сайте строятся довольно просто: для категории "Mobile Phones" ссылка выглядит так: "http://superduperdeal.com/category/Electronics/Phones/Mobile%20Phones", так что вам же будет не особо сложно переделать страничку, правда? — спрашивает заказчик.
Кстати, плюс один кандидату, который, прежде чем писать код, спросит по поводу ссылок; он только что сэкономил себе и вам время на написание неправильного варианта.
Решение для этой задачи в PHP 5.4 может быть примерно таким (разумеется, это не единственный правильный вариант)
function get_category_link(array $categories) {
$link = 'http://superduperdeal.com/' . implode('/',
array_map(
function($cat) { return urlencode($cat);}, $categories
)
);
return $link;
}
function print_category_link(array $categories) {
$last_cat = count($categories)-1;
echo str_repeat(" ", $last_cat*2), '<a href="', get_category_link($categories) , '">', $categories[$last_cat], '</a><br/>';
}
function print_subtree(array $subtree, array $parents) {
foreach ($subtree as $key => $value) {
if (is_array($value)) {
print_category_link(array_merge($parents, array($key)));
print_subtree($value, array_merge($parents, array($key)));
} else {
print_category_link(array_merge($parents, array($value)));
}
}
}
print_subtree($cats, []);
Тут граблей почти нету, надо только помнить, что для массивов с числовыми ключами вызовы array_merge($parents, array($key)) и $parents + array($key) дают совершенно разные результаты.
Да, пока вы решали эту задачу, заказчик прислал смс "Не забудьте про скорость загрузки страницы". Трудно понять, что именно он хотел, но как бы вы ускорили загрузку?
Самый правильный ответ на этот вопрос — кэшировать её. Структура категорий изменяется крайне редко, поэтому необходимости генерировать её для каждого запроса особо нет. Ну а вопрос как именно кэшировать, это уже тема для другого этапа собеседования.
Скачать пример в eval.in: https://eval.in/41670 (к сожалению вывод у него оборачивается в тэг <pre>. Чтобы увидеть правильный вывод, можно запустить код в http://writecodeonline/php)
Вас назначили на проект нового китайского интернет-магазина "SuperDuperDeal.Com". В магазине лежит свыше 9000 товаров, отсортированных по категориям. Вас попросили написать страницу "Карта сайта" и вывести на ней все категории. Проблема в том, что список категорий очень большой и глубина его заранее неизвестна. В качестве исходных данных вам дан массив категорий в виде:
$cats = [
"Electronics" => [
"Phones" => ["Mobile Phones", "Satellite Phones"],
"Tablets",
...
],
...,
"Special Deals"
].
Ваша задача — обойти дерево и вывести его в том порядке, в котором оно вам дано, то есть:
Electronics
Phones
Mobile Phones
Satellite Phones
Tablets
...
...
Special Deals
Уважаемые учащиеся ниже Вы сможете увидеть ответ, перед тем, как ответить, пожалуйста, постарайтесь написать для себя ответ на черновике, и только потом сравните наш ответ с Вашим:
Верно ли наше решение?
Ответ:
Несмотря на простоту задачи, с её помощью можно много чего узнать о кандидате. Для начала, мы хотим узнать, понимает ли кандидат понятие рекурсии. Самым простым решением исходной задачи будет что-нибудь вроде этого:
function print_subtree_simple(array $subtree, $depth) {
foreach ($subtree as $key => $value) {
echo str_repeat(" ", $depth*2);
if (is_array($value)) {
echo "$key<br/>";
print_subtree_simple($value, $depth+1);
} else {
echo "$value<br/>";
}
}
}
print_subtree_simple($cats, 0);
Вывод, правда, у нас получился не очень красивый, без тэгов <nav> или хотя бы <ul> и <li>, но это и не требовалось. Зато здесь есть грабли с забыванием вывести категорию-предка (строка echo "$key<br/>;"). В остальном всё просто.
Правда, нам только что позвонил заказчик и напомнил, что заголовки категорий должны быть ссылками на соотвествующие страницы.
Ссылки на нашем сайте строятся довольно просто: для категории "Mobile Phones" ссылка выглядит так: "http://superduperdeal.com/category/Electronics/Phones/Mobile%20Phones", так что вам же будет не особо сложно переделать страничку, правда? — спрашивает заказчик.
Кстати, плюс один кандидату, который, прежде чем писать код, спросит по поводу ссылок; он только что сэкономил себе и вам время на написание неправильного варианта.
Решение для этой задачи в PHP 5.4 может быть примерно таким (разумеется, это не единственный правильный вариант)
function get_category_link(array $categories) {
$link = 'http://superduperdeal.com/' . implode('/',
array_map(
function($cat) { return urlencode($cat);}, $categories
)
);
return $link;
}
function print_category_link(array $categories) {
$last_cat = count($categories)-1;
echo str_repeat(" ", $last_cat*2), '<a href="', get_category_link($categories) , '">', $categories[$last_cat], '</a><br/>';
}
function print_subtree(array $subtree, array $parents) {
foreach ($subtree as $key => $value) {
if (is_array($value)) {
print_category_link(array_merge($parents, array($key)));
print_subtree($value, array_merge($parents, array($key)));
} else {
print_category_link(array_merge($parents, array($value)));
}
}
}
print_subtree($cats, []);
Тут граблей почти нету, надо только помнить, что для массивов с числовыми ключами вызовы array_merge($parents, array($key)) и $parents + array($key) дают совершенно разные результаты.
Да, пока вы решали эту задачу, заказчик прислал смс "Не забудьте про скорость загрузки страницы". Трудно понять, что именно он хотел, но как бы вы ускорили загрузку?
Самый правильный ответ на этот вопрос — кэшировать её. Структура категорий изменяется крайне редко, поэтому необходимости генерировать её для каждого запроса особо нет. Ну а вопрос как именно кэшировать, это уже тема для другого этапа собеседования.
Скачать пример в eval.in: https://eval.in/41670 (к сожалению вывод у него оборачивается в тэг <pre>. Чтобы увидеть правильный вывод, можно запустить код в http://writecodeonline/php)