4
\$\begingroup\$

Given an integer $value in the range of 1, 2, 3, I want to get an array that starts with $value and proceeds with the remaining two integers from above in arbitrary order. The best I could think of was doing something like this:

switch ($value) {
 case '1':
 $array = [1,2,3];
 break;
 case '2':
 $array = [2,1,3];
 break;
 case '3':
 $array = [3,1,2];
 break;
 }

Is there a shorter and more beautiful way of doing that? Something like that:

$array = push_to_top_of_array($value,[1,2,3]);
Sᴀᴍ Onᴇᴌᴀ
29.5k16 gold badges45 silver badges201 bronze badges
asked May 30, 2018 at 22:50
\$\endgroup\$
3
  • \$\begingroup\$ I should have asked earlier... how is $array used after this code? would there ever be a case where other values would exist in that array? \$\endgroup\$ Commented May 31, 2018 at 15:00
  • \$\begingroup\$ @SamOnela the array goes through a foreach loop. There is no case where other values would exist. \$\endgroup\$ Commented May 31, 2018 at 15:49
  • \$\begingroup\$ Okay- what does the foreach loop do with it? Can you describe the output of the script? For code review, it is best to have a broad picture of what the code does. \$\endgroup\$ Commented May 31, 2018 at 15:50

4 Answers 4

8
\$\begingroup\$

Is there a shorter and more beautiful way of doing that?

  • shorter: yes
  • more beautiful: well, that sounds subjective... you can be the judge of the approaches below.

One approach would be to take off the value using $index with array_splice() and then put it (the first element from that spliced array) at the beginning using array_unshift():

$array = [1, 2, 3];
array_unshift($array, array_splice($array, $value - 1, 1)[0]);

See it demonstrated in this playground example.

Another approach would be to merge the spliced array and the original array using array_merge():

$array = [1, 2, 3];
$array = array_merge(array_splice($array, $value - 1, 1), $array);

See it demonstrated in this playground example.

answered May 30, 2018 at 23:42
\$\endgroup\$
6
\$\begingroup\$

Yes, for three array elements you can write:

$arr = [
 ($value - 1) % 3 + 1,
 ($value + 0) % 3 + 1,
 ($value + 1) % 3 + 1
];

The main ingredient here is the $value modulo 3 expression. The above code contains some redundancies, which I have kept to clearly show the construction of the code. If you absolutely need faster code instead of readable code, the above is equivalent to:

$arr = [
 $value,
 $value % 3 + 1,
 5 - $value - $value % 3
];

Or, the brute force variant:

// To be executed only once in the program.
$arrs = [[], [1, 2, 3], [2, 3, 1], [3, 1, 2]];
// And then, whenever you need it:
$arr = $arrs[$value];
answered May 31, 2018 at 0:20
\$\endgroup\$
5
\$\begingroup\$

I hate hardcoded solutions and prefer generalized ones. You never know when your array will get a 4th element and break all the application.

So a generalized solution would be like

  • get a key for the desired value
  • remove this element from array
  • add its value to the beginning of an array

in PHP it would be like

function push_to_top_of_array($value, $array) {
 $key = array_search($value, $array);
 if ($key === false) {
 throw new \OutOfRangeException("Value not found"); 
 }
 unset($array[$key]);
 array_unshift($array, $value);
 return $array;
}
$value = 2;
$array = [3, 5, 2, 4];
$array = push_to_top_of_array($value, $array);
answered May 31, 2018 at 5:30
\$\endgroup\$
2
\$\begingroup\$

I'm not sure if "more beautiful" means you want a one-liner, but here are two more concise ways to perform the task:

*note, this doesn't validate the $value as being one of the element values -- if this is a necessary component of your project, then please clarify in your question.

Code: (Demo)

$value = 2;
$array = [1, 2, 3];
array_unshift($array,$value); // prepend a duplicate
var_export(array_unique($array)); // kill the original
echo "\n---\n";
$value = 2;
$array = [1, 2, 3];
var_export(array_unique(array_merge([$value],$array))); // prepend a duplicate, kill the original

Output:

array (
 0 => 2,
 1 => 1,
 3 => 3,
)
---
array (
 0 => 2,
 1 => 1,
 3 => 3,
)

On huge arrays, statistics have shown array_flip(array_flip()) out performs array_unique() but that would certainly be less beautiful and if you were dealing with big array I'm sure you would have mentioned that.

answered May 31, 2018 at 15:13
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.