Petr Fořt Fru-Fru
Petr Fořt Fru-Fru

Reputation: 1006

How can I combine multiple values into a single value in an array?

I have this array:

$dataArr = Array(
[0] => Repper
[1] => Pavel
[2] => 7.1.1970
[3] => K.H.Máchy          //start of address
[4] => 1203/2,
[5] => Bruntál            // end of address
[6] => EM092884
[7] => 7.1.2019
);

I need to modify this array so that the address (index 3 to index 6) is below index 3, but indexes 4 and 5 will be removed. Thus, the newly modified array will have indexes from 0 to 5 (6 values). The number of values ​​from index 3 (from the beginning of the address) may be even greater and the address may end, for example, with index number 9. But the beginning of the address is always from index 3.

Expected result:

$dataArr= Array(
[0] => Repper
[1] => Pavel
[2] => 7.1.1970
[3] => K.H.Máchy 1203/2, Bruntál         
[4] => EM092884
[5] => 7.1.2019
);

My idea was as follows. I try something like this: I go through the matrix from index 3 and look for a regular match (the value just after the end of the address). Until the array value matches the regex, I compile the values ​​into string.

$address = NULL;   //empty variable for address from $dataArr

foreach($dataArr as $k => $val) {
    if($k >= 3) {
        if(! preg_match('/^\[A-Za-z]{2}\d{6}/', $val)) {
           $address .= $val;
     //Then put this variable $address in position $dataArr[3]
        }
     }
 }

But it seems that the 'if' condition with preg_match is still true. I need the foreach cycle to stop before index 6, but the cycle is still working, to last value of array. Where's the mistake? This problem hinders me in completing the script. Thank you very much.

Upvotes: 1

Views: 271

Answers (2)

Don't Panic
Don't Panic

Reputation: 41820

One other possibility, pop off the beginning and end

$first = array_splice($dataArr, 0, 3);
$last = array_splice($dataArr, -2);

Then implode the remaining part and put it all back together.

$dataArr = array_merge($first, [implode(' ', $dataArr)], $last);
// or in PHP 7.4
$dataArr = [...$first, implode(' ', $dataArr), ...$last];

This should work regardless of the size of the address, but it does totally depend on the last two elements after the address always being present, so if there's any way those would be missing sometimes you'll need something a little more complicated to account for that.

Upvotes: 1

Why overcomplicate things with regexp and loops? Just literally do what you describe: if your address runs from n to m, take the array slice from n to m, implode that to a string, set array[n] to that string, and then remove fields [n+1...m] from your array:

function collapse_address($arr, $start, $end) {
    $len = $end - $start;
    // collapse the address:
    $arr[$start] = join(" ", array_slice($arr, $start, $len));
    // remove the now-duplicate fields:
    array_splice($arr, $start + 1, $len - 1);
    // and we're done.
    return $arr;
}

$arr = Array(
'Repper',
'Pavel',
'7.1.1970',
'K.H.Máchy',          //start of address
'1203/2',
'Bruntál',            // end of address
'EM092884',
'7.1.2019'
);

$arr = collapse_address($arr, 3, 6);

result:

Array
(
    [0] => Repper
    [1] => Pavel
    [2] => 7.1.1970
    [3] => K.H.Máchy 1203/2 Bruntál
    [4] => EM092884
    [5] => 7.1.2019
)

Of course, you might not want $end to be exclusive, but that's up to you.

Upvotes: 0

Related Questions