У меня есть слайдер с циклом (за последним элементом следует первый элемент), и я хочу установить другой цвет (на основе диапазона из 3 цветов).
Таким образом, есть 2 условия: предыдущий цвет и следующий цвет не должны быть одинаковыми И количество слайдов (элементов в массиве) может варьироваться.
Хороший пример:
Array
(
[0] => yellow
[1] => blue
[2] => red
[3] => yellow
[4] => red
)
Плохой пример (потому что элементы 0 и 4 имеют одинаковый цвет):
Array
(
[0] => yellow
[1] => blue
[2] => yellow
[3] => red
[4] => yellow
)
Еще один плохой пример с большим количеством элементов (потому что элементы 2 и 3 имеют одинаковый цвет):
Array
(
[0] => yellow
[1] => blue
[2] => red
[3] => red
[4] => blue
[5] => yellow
[6] => blue
)
Это то, что я пытаюсь, но я не думаю, что это хороший способ:
$i = 0;
$bgcolors = array();
foreach($slides as $slide) {
switch ($i % 3) {
case 0:
$bgcolors[] = 'yellow';
break;
case 1:
$bgcolors[] = 'blue';
break;
case 2:
$bgcolors[] = 'red';
break;
}
if ((count($slides) - $i) % 3 == 0) $i = 0;
$i++;
}
но я не думаю, что это хороший способ
Это относительно элегантный и эффективный способ гарантировать, что у вас не будет последовательных совпадений цветов за один проход результатов. Но это может быть более элегантно, если использовать метод, предложенный Йероеном.
Однако это не решает проблему, когда список оборачивается. Очевидно, что при неизвестном количестве слайдов (M) существует вероятность 1 в N (где N — количество цветов), что 1-му слайду будет присвоен тот же цвет, что и последнему. Но это легко понять, когда это так:
M % N = 1
Так что, пока M% N не единица, вам не о чем беспокоиться. Когда M% N равно 1, вам нужно беспокоиться только об изменении цвета или первый или последний слайд. Ради аргумента, мы изменим цвет последнего.
Так что остается проблема, какой цвет выбрать.
При отсутствии изменений последний слайд будет иметь тот же цвет, что и первый, и мы не можем изменить его на цвет ранее в цикле, так как это сделает его таким же, как и предпоследний слайд.
Решение Joeroen довольно грязное — найдите цвет, который не использовался на предыдущих или более поздних слайдах, и примените его. Он использует больше кода, чем необходимо. Вы просто выбираете второй цвет в списке.
Однако Йерун ошибается, говоря, что проблему можно решить двумя цветами (или меньше!). Никакое количество кода не поможет, если только 2 цвета и нечетное количество слайдов больше 1.
следовательно:
$colors = ['yellow', 'blue', 'red'];
if (count($slides)>count($colors) && 3>count($colors)) {
trigger_error("unsolvable");
}
$i = 0;
$bgcolors = array();
foreach($slides as $slide) {
$bgcolors[] = $colors[$i % count($colours)];
$i++;
}
if (1 < count($slides) && 1 == count($slides) % count($colors)) {
$bgcolors[count($slides)-1]=$colors[1];
}
Вы должны начать с размещения ваших цветов в массиве.
Затем в конце массива вам нужно добавить логику, чтобы убедиться, что ни предыдущий, ни первый цвет не используются:
$colors = ['yellow', 'blue', 'red'];
$i = 0;
$bgcolors = array();
foreach($slides as $slide) {
$bgcolors[] = $colors[$i % 3];
$i++;
if ($slide == end($slides) {
$j = $i;
while ($bgcolors[$i - 1] === $colors[$j % 3] || $bgcolors[0] === $colors[$j % 3]) {
$j++;
}
$bgcolors[] = $colors[$j % 3];
}
}
Обратите внимание, что вам нужно добавить условия, если ваш массив цветов или ползунков может иметь 2 элемента или меньше …
Предполагая, что цвета могут быть случайными (за исключением упомянутых ограничений, конечно):
$slides = array('slide1', 'slide2', 'slide3', 'slide4', 'slide5');
$colors = array('red', 'blue', 'yellow');
$bg_colors = array();
foreach ($slides as $key=>$value) {
if ($key == 0) { // First slide
$bg_colors[] = $colors[mt_rand(0, 2)]; // Get random color
} else { // Other slides
$usable_colors = $colors; // Duplicate colors array
$usable_colors = array_values(array_diff($usable_colors, array($bg_colors[$key-1]))); // Remove last used color and reset keys
if ($key == count($slides) -1) { // Last slide
$usable_colors = array_values(array_diff($usable_colors, array($bg_colors[0]))); // Remove first used color and reset keys
}
$bg_colors[] = $usable_colors[mt_rand(0, count($usable_colors)-1)]; // Get random color
}
}
Чистый способ сделать это — запросить все возможные цвета, отличные от последнего и первого в слайдере, а затем подобрать случайный.
function getColorsForElements( $numbersOfElements ) {
$colors_array = array('red', 'blue', 'yellow');
$bg_colors = array();
for ($i = 0; $i < $numbersOfElements; $i++) {
if ($i == $numbersOfElements - 1 )
$first_color = reset($bg_colors);
else
$first_color = false;
$last_color = end($bg_colors);
$possible_colors = array_diff($colors_array, array($first_color, $last_color) );
$index = array_rand($possible_colors, 1);
array_push($bg_colors, $possible_colors[$index] );
}
return $bg_colors;
}
Пример использования getColorsForElements( 5 )
что дает в результате:
Array
(
[0] => yellow
[1] => blue
[2] => red
[3] => blue
[4] => red
)
$colors = ['yellow', 'blue', 'red'];
$bgcolors = array($colors[2]);
for ($i = 1; $i < count($slides); ++$i) {
$bgcolors[] = $colors[$i%2];
}
Это соответствует вашим двум условиям. Но теперь вы, вероятно, скажете мне третий, потому что это не может быть так просто 🙂
Как я понимаю ваш вопрос, вот решение
$i = 0;
$bgcolors = array();
foreach($slides as $slide) {
if ($i > 2) $i = 0;
switch ($i) {
case 0:
$bgcolors[] = 'yellow';
break;
case 1:
$bgcolors[] = 'blue';
break;
case 2:
$bgcolors[] = 'red';
break;
}
$i++;
}