1

I have an associative array, with some of the values in "CAT" having multiple words, separated by a comma.

I would like to split those into separate array entries (each comma separated word to create another array entry) as shown below.

I know that I can use explode() to separate those values with commas, but not sure on how to create a new array entry from it?

$categories = explode(',', $details[0]['CAT']);

Current array structure:

Array
(
    [0] => Array
        (
            [ID] => 50829
            [CAT] => "furniture,home,garden"
        )

    [1] => Array
        (
            [ID] => 50832
            [CAT] => "kids"
        )

    [2] => Array
        (
            [ID] => 50854
            [CAT] => "toys"
        )
)

Desired result:

Array
(
    [0] => Array
        (
            [ID] => 50829
            [CAT] => "furniture"
        )

    [1] => Array
        (
            [ID] => 50829
            [CAT] => "home"
        )

    [2] => Array
        (
            [ID] => 50829
            [CAT] => "garden"
        )

    [3] => Array
        (
            [ID] => 50832
            [CAT] => "kids"
        )

    [4] => Array
        (
            [ID] => 50854
            [CAT] => "toys"
        )
)

Really appreciate your help!

2 Answers 2

1

You can simply use a foreach to recreate a new array. For each category in the "CSV string", you can add the "ID"+"new CAT" in the output array:

$array = [
    ['ID' => 50829, 'CAT' => 'furniture,home,garden'],
    ['ID' => 50832, 'CAT' => 'kids'],
    ['ID' => 50854, 'CAT' => 'toys'],
];

$out = [];                              // output array
foreach ($array as $item) {             // for each entry of the array
    $cats = explode(',', $item['CAT']); // split the categories
    foreach ($cats as $cat) {           // for each cat
        $out[] = [                      // create a new entry in output array
           'ID'  => $item['ID'],        // with same ID
           'CAT' => $cat,               // the "sub" category
        ];
    }
}

var_export(array_values($out));
array (
  0 => 
  array (
    'ID' => 50829,
    'CAT' => 'furniture',
  ),
  1 => 
  array (
    'ID' => 50829,
    'CAT' => 'home',
  ),
  2 => 
  array (
    'ID' => 50829,
    'CAT' => 'garden',
  ),
  3 => 
  array (
    'ID' => 50832,
    'CAT' => 'kids',
  ),
  4 => 
  array (
    'ID' => 50854,
    'CAT' => 'toys',
  ),
)

Or to create a same array without "CAT":

$out = [];
foreach ($array as $item) {
    $cats = explode(',', $item['CAT']);
    unset($item['CAT']);                  // unset the original "CAT"
    foreach ($cats as $cat) {
        $out[] = $item + ['CAT' => $cat]; // copy $item and add "CAT"
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks so much for such a clean explanation. I have one extra question related to this. If I'd have more indexes than just ID and CAT, lets say 20 different indexes, do I need to hardcode them in there like: $out[] = [ 'ID' => $item['ID'], 'ID2' => $item['ID2'], 'ID3' => $item['ID3']... and so on... 'CAT' => $cat, ]; or can I include another loop in there, that will set all of the indexes to be the same as before, apart from CAT? Thank you
I've added another the to this, using unset and array operator + at the bottom of the answer.
1

While there are always very cryptic tricks you can use, it is often very easy to do this work exactly as you describe you want it done. You want to explode the CAT index and create a new array with each value tied to the original index. So, do exactly that:

// Assume $old_array is your original array.
$new_array = array(); // Originally empty.
foreach($old_array as $e) { // For each element in the old array...
  $cats = explode(',',$e['CAT']);
  // $cats is every word exploded (one word if there is no comma).
  foreach($cats as $cat) { // For each word in $cats...
    $new_array[] = array('ID'=>$e['ID'], 'CAT'=>$cat);
    // Add a pair to the new array that has the ID and the cat word.
  }
}

When done, $new_array is the exploded version that you asked for.

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.