1

I have the following array:

array(a, a, a, b, b, c, c, c, c, d, d);

When I loop through it and echo it, the result is:

a
a
a
b
b
c
c
c
c
d
d

How ever I want to echo it in such a way that it displays:

a
b
c
d
a
b
c
d
a
c
c

Here is the array in a grid to better explain what im trying to achieve

Current
a a a b
b c c c
c d d

What im tryin to do
a b c d
a b c d
a c c

How would I do this?

Seeing some of your answers, its clear I didnt explain it well enough :/

i should have included what the array keys should look like:

0a 1a 2a 3b
4b 5c 6c 7c
8c 9d 10d

0a 3b 6c 9d
1a 4b 7c 10d
2a 5c 8c

Heres how i need the arrays to be organised, by key

0a 
1a 
2a 
3b
4b 
5c 
6c 
7c
8c 
9d 
10d

0a 
3b 
6c 
9d
1a 
4b 
7c 
10d
2a 
5c 
8c
2
  • 1
    Have an algorithm that would meet your needs. Have you created one? Commented Jan 2, 2011 at 5:22
  • I cannot get my head around algorithms :s Im thinking i would need something to do with the Knapsack problem but would have no idea how to implement it Commented Jan 2, 2011 at 5:24

4 Answers 4

1

If I correctly understood your specification, this should work:

<?php

function magicFunction($input) {
    $output = array();

    sort($input);

    $startingCount = count($input);

    for ($j=0; $j<count($input); $j++) {
        $lastValue = NULL;

        for ($i=0; $i<count($input); $i++) {
            //var_dump($input[$i]);
            if ($input[$i] !== NULL && $input[$i] !== $lastValue) {

                $output[] = $input[$i];
                $lastValue = $input[$i];
                $input[$i] = NULL;
            }
        }
        //echo '<hr />';
        if (count($output) == $startingCount) {
            break;
        }
    }

    return $output;
}

$array = array('z','a','a','a','b','b','c','c','c','c','d','d','z');

$result = magicFunction($array);
echo '<pre>' . print_r($result, true) . '</pre>';

?>

gives output of:

Array
(
    [0] => a
    [1] => b
    [2] => c
    [3] => d
    [4] => z
    [5] => a
    [6] => b
    [7] => c
    [8] => d
    [9] => z
    [10] => a
    [11] => c
    [12] => c
)

I added z to the input array (twice) to make it easier for me to test.

You can uncomment the commented lines to help see how my function works.

There is probably a more efficient way of doing this (or at least minor performance tweaks to this method), but I'm not going to look at it too hard right now because I might have misinterpreted your question. Anyway, it shouldn't matter unless your input array is really massive.

Sign up to request clarification or add additional context in comments.

Comments

1

You can use something like this to rotate the array around a certain stride/width:

function rotate_array(&$array, $width) {
    $newarr = array();

    for ($stride = 0; $stride < $width; $stride++) {
        for ($i = $stride; $i < count($array); $i += $width) {
            $newarr[] = $array[$i];
        }
    }

    return $newarr;
}

This test script:

$arr = array('a', 'a', 'a', 'b', 'b', 'c', 'c', 'c', 'c', 'd', 'd');

print_r($arr);
print_r(rotate_array($arr, 3));

Will output this:

Array
(
    [0] => a
    [1] => a
    [2] => a
    [3] => b
    [4] => b
    [5] => c
    [6] => c
    [7] => c
    [8] => c
    [9] => d
    [10] => d
)
Array
(
    [0] => a
    [1] => b
    [2] => c
    [3] => d
    [4] => a
    [5] => b
    [6] => c
    [7] => d
    [8] => a
    [9] => c
    [10] => c
)

Which looks like the output you wanted. But it's unclear from your question exactly how you want this result produced. It looks to me like you want to display every third item starting from the first item, then every third item starting from the second item, and so on. If this is not what you are trying to accomplish then please provide better sample data so your goal is clearer.

Comments

1

Loop through the array like this:

Example:

function noRepeatArray($array){
    $lastChar = "";
    for($j = 0;$j < count($array);$j++){
        for($i = 0;$i < count($array);$i++){
            if($array[$i] != $lastChar && strlen($array[$i]) > 0){
                echo $array[$i] ."<br />";
                $lastChar = $array[$i];
                $array[$i] = '';
            }
        }
        $lastChar = "";
    }
}

This will loop through the array and not allow a character to be repeated unless it is the only character left (in your example, "c").

Comments

1

Another way (assumes the array is already sorted, as in your example):

$vals = array_count_values($array);
while (!empty($vals)) {
    foreach ($vals as $key => & $ct) {
        echo $key . "\n";
        if (!--$ct) {
            unset($vals[$key]);
        }
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.