0

Similar to this question but for PHP. I want to concatenate an array of strings but ignore blanks.

For instance, suppose I want to build a full_name attribute in Laravel using $this->title, $this->first_name, and $this->last_name, each separated by single space. The simplest thought I had was to put them all into an array and pass it into implode() as in below:

implode(' ', [$this->title, $this->first_name, $this->last_name]);

However I don't know whether those values are actually going to be set or not. And if they are set, I don't want empty strings to pollute the output with multiple spaces between non-empty elements. Is there a built-in function or at least a simpler/shorter way to do the below?

public function concatenateStringsFromArray($glue = ' ', $arrayOfStrings)
{
    $result = '';
    foreach($arrayOfStrings as $piece)
        $result .= isset($piece) ? $piece . $glue : '';
    return $result;
}
Erich
  • 2,408
  • 18
  • 40
  • Did you try with `trim()` function? – unclexo Feb 20 '20 at 04:27
  • @unclexo i can't see how that would prevent consecutive spaces from appearing due to nulls/blanks in the middle of the array. – Erich Feb 20 '20 at 04:37
  • I can't see what your goal is. What should come out of this input array ['a', ' b c',null, ' ','def '] – jspit Feb 20 '20 at 06:56
  • @jspit good question -- i was assuming that provided strings would be single words without any whitespace (or at least [trimmed](https://github.com/laravel/framework/blob/e04a7ffba8b80b934506783a7d0a161dd52eb2ef/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php)). to fail the test, strings should be not null or empty (i.e. `''`). so your array should result in `a b c def ` i think. – Erich Feb 20 '20 at 14:24

4 Answers4

2

array_map with trim as function removes all spaces at the beginning and end of a string, not in the middle. array_filter removes then all elements that are empty, including zero and "".

$arrayOfStrings = ['a', 'b    c',null, '    ','ef ','  012'];

$result = implode(' ', array_filter(array_map('trim',$arrayOfStrings)));

echo '<pre>'.$result;  //a b    c ef 012

I wrote everything on one line because you wanted it to be short.

jspit
  • 7,276
  • 1
  • 9
  • 17
  • 1
    produces `"a b c ef 012"`. this is a good substitute for unclexo's [answer](https://stackoverflow.com/a/60313125/4468423) if you need to do clean up first. – Erich Feb 20 '20 at 14:40
1

Apply trim() function on each array element. See the following example:

<?php

$arrayOfStrings = ['a', ' b c',null, ' ','def '];

echo implode(' ', array_filter($arrayOfStrings, function($element) { 
    return trim($element); 
}));

The code above outputs "a b c def ". Notice the space after "def ".

This means trim() function with array_filter() function's callback function doesn't trim space from the right side. To address this issue, you should use trim() function with array_filter() and array_map() functions. Because array_map() function removes spaces from both sides. See the following example:

<?php

echo implode(' ', array_filter(array_map('trim', $arrayOfStrings)));

The code above outputs "a b c def"

By the way thanks to @jspit for the good catch!

unclexo
  • 3,691
  • 2
  • 18
  • 26
  • that works well! on @jspit's test array above, produces `"a b c def "`. – Erich Feb 20 '20 at 14:32
  • @Erich : The result is not the same. You have to output an echo "
    " in advance to see all spaces!
    – jspit Feb 20 '20 at 14:58
  • @jspit your comment on the question i only saw `['a', ' b c',null, ' ','def ']`. was there a space in front of the `a`? – Erich Feb 20 '20 at 15:01
  • @jspit i'm not formatting the output for an html canvas, so no need for `
    `
    – Erich Feb 20 '20 at 15:07
  • 1
    The '
    ' only serves to make the spaces visible in the browser. However, the spaces are in the string. Do a var_dump() and also look at the number of characters. I don't know if the difference bothers you.
    – jspit Feb 20 '20 at 17:17
  • @jspit yes, you're right. Though I tested on command line tool. – unclexo Feb 20 '20 at 17:45
0

Adapted from an example using array_filter:

return implode($glue, array_filter($arrayOfStrings, function($element) { 
    return $element !== null && $element !== ''; 
}));
Mike Doe
  • 16,349
  • 11
  • 65
  • 88
Erich
  • 2,408
  • 18
  • 40
0

array_filter() should do the trick. Simply calling implode($glue,array_filter($array)) should give you what you want, by filtering out all elements of the given array which resolve to false (0, null and '' among others). If you need 0 or other values which resolve to boolean false as valid values you can use a custom callback:

array_filter($array, function($value) { return !is_null($value) && $value !== ''; })
brett
  • 744
  • 5
  • 15