如何破坏多维数组?

I have an array of arrays like:

$array = [["1.","COTV_LITE(1800)"],["2.","COTV_PREMIUM(2200)"]]

Now, I want to implode this array such that it would return something like this:

  1. COTV_LITE(1800)
  2. COTV_PREMIUM(2200)

How do I achieve this? Calling just the implode() function did not work:

implode ('<br>', $array);

Try this

$items = [["1.","COTV_LITE(1800)"],["2.","COTV_PREMIUM(2200)"]];
$imploded = [];
foreach($items as $item) {
    $item_entry = implode(' ', $item);
    echo $item_entry . '<br/>'; // display items
    $imploded[] = $item_entry;
}
// your desired result is in $imploded variable for further use

You can call array_map() to implode the nested arrays:

echo implode('<br>', array_map(function($a) { return implode(' ', $a); }, $array));

DEMO

output:

1. COTV_LITE(1800)<br>2. COTV_PREMIUM(2200)

You can use variable length arguments variadic in PHP >= 5.6

Option1

$items = [["1.","COTV_LITE(1800)"],["2.","COTV_PREMIUM(2200)"]];
echo implode(' ',array_merge(...$items));

Output

1. COTV_LITE(1800) 2. COTV_PREMIUM(2200)

This is more of a precursor for the next option.

Option2

If you want to get a bit more creative you can use preg_replace too:

$items = [["1.","COTV_LITE(1800)"],["2.","COTV_PREMIUM(2200)"]];
$replace = [
    '/^(\d+\.)$/' => '<li>\1 ',
    '/^(\w+\(\d+\))$/' => '\1</li>'
];

echo '<ul>'.implode(preg_replace(array_keys($replace),$replace,array_merge(...$items))).'</ul>';

Output

<ul><li>1. COTV_LITE(1800)</li><li>2. COTV_PREMIUM(2200)</li></ul>

Option3

And lastly using an olordered list, which does the numbers for you. In this case we only need the second item from the array (index 1):

$items = [["1.","COTV_LITE(1800)"],["2.","COTV_PREMIUM(2200)"]];

echo '<ol><li>'.implode('</li><li>',array_column($items,1)).'</li></ol>';

Output

<ol><li>COTV_LITE(1800)</li><li>COTV_PREMIUM(2200)</li></ol>

Personally, I would put it in the ol that way you don't have to worry about the order of the numbers, you can let HTML + CSS handle them. Also it's probably the easiest and most semantically correct way, But I don't know if the numbering in the array has any special meaning or not.

In any case I would most definitely put this into a list to render it to HTML. This will give you a lot more options for styling it, later.

Update

want to use option 1. But how do I put each option on a different line using <br>

That one will put the <br> between each array element:

   echo implode('<br>',array_merge(...$items));

Output

  1.<br>COTV_LITE(1800)<br>2.<br>COTV_PREMIUM(2200)

The only way to easily fix that (while keeping the array_merge) is with preg_replace, which is the second one. So I will call this:

Option 1.2

$items = [["1.","COTV_LITE(1800)"],["2.","COTV_PREMIUM(2200)"]];

echo implode(preg_replace('/^(\w+\(\d+\))$/',' \1<br>',array_merge(...$items)));

Output

1. COTV_LITE(1800)<br>2. COTV_PREMIUM(2200)<br>

Sandbox

Basically there is no way to tell where the end item is after merging them. That operation effectively flattens the array out and gives us something like this:

 ["1.","COTV_LITE(1800)","2.","COTV_PREMIUM(2200)"]

So that Regex does this 'COTV_PREMIUM(2200)' becomes ' COTV_PREMIUM(2200)<br>'. This is just a way of changing that without having to dip into the array with some logic or something. WE wind up with this modification to the array:

["1."," COTV_LITE(1800)<br>","2."," COTV_PREMIUM(2200)<br>"]

Then with implode we just flatten it again into a string:

 "1. COTV_LITE(1800)<br>2. COTV_PREMIUM(2200)<br>"

The Regex ^(\w+\(\d+\))$

  • ^ - Match start of string
  • (...) - capture group 1
    • \w+ - match any working character a-zA-Z0-9_ one or more, eg. COTV_PREMIUM
    • \( - match the ( literally
    • \d+ - match digits 0-9 one or more, eg 2200
    • \) - match the ) literally
  • $ - match end of string

So this matches the pattern of the second (or even) items in the array, then we replace that with this:

The Replacement ' \1<br>'

  • {space} - adds a leading space
  • \1 - the value of capture group 1 (from above)
  • <br> - append a line break

Hope that makes sense. This should work as long as they meet that pattern. Obviously we can adjust the pattern, but with such a small sample size it's hard for me to know what variations will be there.

For example something as simple as (.+\))$ will work TestIt. This one just looks for the ending ). We just need somethng to capture all of the even ones, while not matching the odd. Regular expressions can be very confusing the first few times you see them, but they are extremely powerful.

PS - I added a few links to the function names, these go the the PHP documentation page for them.

Cheers!