Reorganizing an array: odd entries as KEY, even entries as VALUE
Asked Answered
G

8

12

I'm trying to finish up a URL router that I created for my custom MVC framework. I have a list of parameters that I dissected from the URL, but the problem is that they only have numerical keys. What I want to do is set it up so the first value in the $params array will be the KEY and then the second value in the array is the VALUE of the first KEY. But I need to take it beyond that even further. Essentially, I need all odd number key's value in the array to be the new KEY and the even number key's value to be the value.

Example:

This is how it's CURRENTLY set up:

Array
(
  [0] => greeting
  [1] => hello
  [2] => question
  [3] => how-are-you
  [4] => response
  [5] => im-fine
)

This is how it NEEDS to be (after conversion):

Array
(
  [greeting] => hello
  [question] => how-are-you
  [response] => im-fine
)

Would it be easier to create this type of array when I explode the string by the '/' delimiter when I'm taking it out of the URL string? If so, what would be the best function for that?

It's probably a simple solution, because I'm sure this is a common issue, but any enlightenment?

Gifferd answered 14/12, 2011 at 8:30 Comment(1)
I think I was with you until you say that you want the first index (0) to be the key and then you say that you want the odd indexes to be the key. Do you mean: starting from zero, take the first value as key, second as value and put in a map, and do so for every key/value pair?Deville
E
12

Maybe use array_splice() for that?

$result = array();

while (count($urls)) {
    list($key,$value) = array_splice($urls, 0, 2);
    $result[$key] = $value;
}

This will extract the first two entries from the URL list and use those as key and value for the resulting array. Repeats, until the source list is empty.

Earthbound answered 14/12, 2011 at 8:32 Comment(2)
I will try this... If there is an uneven amount of entries in the array, will it export an error?Gifferd
@Gifferd yup, it would. As array_splice would yield a single-element array, while list expects two elements. You'll get Notice: Undefined offset: 1 in .... on line ...Autonomic
A
1

Something like:

$data = array (
  'greeting',
  'hello',
  'question',
  'how-are-you',
  'response',
  'im-fine',
);

$new = array();

for ($i = 0, $lim = sizeof($data); $i < $lim; $i += 2) {
  $new[$data[$i]] = isset($data[$i + 1]) ? $data[$i + 1] : null;
}

print_r($new);
Autonomic answered 14/12, 2011 at 8:34 Comment(0)
B
1

And the one-liner we are all searching for:

array_combine(array_filter($urls, function ($k) {return !($k&1);}, ARRAY_FILTER_USE_KEY), array_filter($urls, function ($k) {return ($k&1);}, ARRAY_FILTER_USE_KEY));
Burlburlap answered 28/9, 2020 at 9:32 Comment(0)
S
0

I don't know if it the best solution but what I did is

           $previousElement = null;
            foreach ($features as $key => $feature) {
                //check if key is even, otherwise it's odd
                if ($key % 2 === 0) {
                    $features[$feature] = $feature;
                } else {
                    $features[$previousElement] = $feature;
                }
                //saving element so I can "remember" it in next loop
                $previousElement = $feature;
                unset($features[$key]);
            }
Scopp answered 19/4, 2017 at 10:44 Comment(0)
G
0

The best way to do it is with chunking it and using it in list.

$array = array("greeting", "hello", "question", "how-are-you", "response", "im-fine");

$assoc = array();
   foreach (array_chunk($array, 2) as $pair) {
   list($key, $value) = $pair;
   $assoc[$key] = $value;
}

var_export($assoc);

/*
   array (
       'greeting' => 'hello',
       'question' => 'how-are-you',
       'response' => 'im-fine',
  )
*/

found here

Glyptodont answered 16/1, 2018 at 20:29 Comment(0)
S
0

just because no one else has pointed it out, this works and is at least as good as the built in functions for performance:

$array = array("greeting", "hello", "question", "how-are-you", "response", "im-fine");
$res = array();
for($i=0; $i < count($array); $i+=2){
    $res[$array[$i]] = $array[$i+1];
}
Saxton answered 16/1, 2018 at 20:47 Comment(0)
O
0
foreach($data as $key => $value) {
  if($key % 2 === 0) {
    $final_array[$value] = $data[$key + 1];
  }
}
Ottava answered 22/7, 2021 at 6:11 Comment(1)
A little bit of supporting text would help this code-only answer. Especially since you've had 10 years to come up with this.Evangelist
P
0

Another concise way to do this would be to call array_chunk() inside of a body-less foreach loop and use array destructuring syntax to populate the result array with associative elements.

Code: (Demo)

$array = ["greeting", "hello", "question", "how-are-you", "response", "im-fine"];    
foreach (array_chunk($array, 2) as [$key, $result[$key]]);
var_export($result);

or even more concisely, call array_chunk() inside of array_column() for a fully functional-style approach (Demo)

var_export(
    array_column(array_chunk($array, 2), 1, 0)
);

Result (from either snippet):

array (
  'greeting' => 'hello',
  'question' => 'how-are-you',
  'response' => 'im-fine',
)
Patrilineage answered 6/7 at 14:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.