如何获取最后一个元素既不是前一个元素也不是第一个元素的数组?

时间:2016-09-16 10:08:32

标签: php modulo

我有一个带有循环的滑块(最后一个元素后跟第一个元素)并且想要设置不同的颜色(基于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++;
}

6 个答案:

答案 0 :(得分: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个或更少的元素,则需要添加条件...

答案 1 :(得分:1)

  

但我不认为这是好方法

这是一种相对优雅和有效的方法,可确保您在一次通过结果时没有连续匹配的颜色。但使用jeroen提出的方法可能会更优雅。

然而,它没有解决列表所包含的问题。显然,对于未知数量的幻灯片(M),第一张幻灯片将被分配与最后一张幻灯片相同的颜色,其中有一个N的机会(其中N是颜色的数量)。但是在这种情况下很容易解决:

M % N = 1

因此,只要M%N不是一个,那么您就不必担心这个问题了。当M%N为1时,您只需要担心更改的颜色第一张或最后一张幻灯片。为了论证,我们将改变最后一个的颜色。

这样就可以解决选择哪种颜色的问题。

如果没有更改,最后一张幻灯片将与第一张幻灯片颜色相同,我们无法将其更改为周期中较早的颜色,因为这将使其与倒数第二张幻灯片相同。

Joeroen的解决方案相当混乱 - 搜索之前或之后幻灯片中未使用的颜色并应用它。它使用的代码多于必要的代码。您只需在列表中选择第二种颜色即可。

然而,jeroen说这个问题可以用2种颜色(或更少!)来解决是错误的。如果只有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];
  }

答案 2 :(得分:0)

假设颜色可以是随机的(当然除了上述限制之外):

$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
    }
}

答案 3 :(得分:0)

一种干净的方法是要求所有可能的颜色与最后一个和滑块中的第一个颜色不同,然后随机选择一个颜色。

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
)

答案 4 :(得分:0)

$colors = ['yellow', 'blue', 'red'];
$bgcolors = array($colors[2]);
for ($i = 1; $i < count($slides); ++$i) {
    $bgcolors[] = $colors[$i%2];
}

这符合您的两个条件。但现在你可能会告诉我第三个,因为它不是那么容易: - )

答案 5 :(得分:-1)

据我了解你的问题,这是解决方案

$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++;
}