PHP search and merge array elements if they have an identical substring

I have this php array:

    Array (
     [0] => blablabla blablabla blablabla  H999999 blablabla H999999 blablabla
    
     [1] => blablabla blablabla blablabla  H999996  blablabla blablabla
    
     [2] => blablabla blablabla blablabla  H999999  blablabla blablabla
    
     [3] => blablabla blablabla blablabla  H999997  blablabla H999997 blablabla
    
    [4] => blablabla blablabla blablabla  H999996  blablabla
    
     )

What I want to do is merge into one element the items that have the same H______. Like the folowwing for the previous example:

Array (
     [0] => blablabla blablabla blablabla  H999999  blablabla H999999 blablabla + blablabla blablabla blablabla  H999999  blablabla blablabla

     [1] => blablabla blablabla blablabla  H999996  blablabla blablabla + blablabla blablabla blablabla  H999996  blablabla

     [2] => blablabla blablabla blablabla  H999997  blablabla blablabla

     )

I dont understand that much of arrays. But here I have to find the item of the array the substring H_____ and compare with other items and if equal merge. I found examples of removing duplicates and finding exactly same item, but this is not the case.

$final = array();
foreach ($input AS $string) {
   $shards = explode(" ",$string);
   $final[$shards[3]][] = $string
}
foreach($final as &$string) {
    $string = implode(" + ",$string);
}

(incomplete, but theoretically sound)

1 Like

Tested and it is sound (as long as the extra spaces aren’t correct before the numbers, otherwise its an index of 4 in the first foreach loop). Wow, I would have never in my wildest dreams have guessed to do it that way. Talk about a learning experience! Thanks StarLion!

Scott

1 Like

It’s a bit of a weak solution (relies on string positioning, two foreach loops to do one sort), and a bit incomplete (should create an empty array in $final[$shards[3]] if $final[$shards[3]] is not set first), but it was the only way i could come up with that imploded the + symbols in. (Without the +, it would be as simple as $final[$shards[3]] .= $string with no second loop)

EDIT: I suppose i could do it as string manipulation with a isset check instead… mumbles, pokes at it a bit more

$final = array();
foreach ($input AS $string) {
   $shards = explode(" ",$string);
   $final[$shards[3]] = (isset($final[$shards[3]])) ? $final[$shards[3]]." + ".$string : $string;
}
2 Likes

Hi that is awesome! And works for the example I gave, however unfortunately not always I have the same number of spaces, characters before and after the H______
It could be something like this:

 Array (
     [0] =>
"BLABLABLA   08.09.15

 00.00.00  BBB  BBB  X3 0000  00:00   00:00
 00.00.00  BBB  BBB  TP 0000  00:00
 FNC015P blablablablablabla    blablabla
  1  blablabla     blablabla
 am blablabla blablabla
 blablabla blablabla blablabla
 blablabla
 blablabla
 bblablabla blablabla
 H999999  blablabla
blablabla
blablabla
blablabla
blablabla "


    [1] => 
"00.00.00  BBB  BBB  X3 0000  00:00   00:00
 00.00.00  BBB  BBB  TP 0000  00:00
 FNC015 blablablablablabla    blablabla
   blablablablablabla    blablabla
 blablablablablabla    blablabla
 blablablablablabla    blablabla
 blablablablablabla    
 blablablablablabla    bla
  blablablablablabla    blablabla
 H999996   blablablablablabla    blablabla
 blablablablablabla    bla
 blablablablablabla   
 blablablablablabla    blabla
 blablablablablabla    blablabla
 blablablablablabla    blablabla
 blablablablablabla    blablabla"

    [2] =>
"BLABLABLA   08.09.15
  00.00.00  BBB  BBB  X3 0000  00:00   00:00
 00.00.00  BBB  BBB  TP 0000  00:00
 FNC234  blablablablablabla    blablabla
 blablablablablabla    blablabla
blablablablablabla    blablabla
 blablab
 blablablablablabla    blablablablablablablablabla    blablabla
 blablab
H999999 blablablablablabla    blablabla
blablablablablabla    blablablablablablablablabla    blablabla"

[3] =>
"BLABLABLA   22.09.15
BLABLABLA
 22.09.15  STR  FNC  X3 2810  14:20   17:25
 29.09.15  FNC  STR  X3 2811  18:15
 FNC042  blablablablablabla    blablabla
 blablablablablabla    blablablablablablablablabla    blablabla
blablablablablabla    blablabla
blablab
 H999997  blablablablablabla    blablabla"
)

So lesson learned: Always give as much detail as you can, or else your answer will be incomplete.

I’ll give you the hints this time though, rather than the code.
Hint #1: You only need to completely change one of the lines above.(Though error-checking may add an additional line, if desired). The other line only requires variable replacement.
Hint #2: preg_match to find the key. Your pattern for the regex would be “#H\d+#”.

Hi, with some help I got there:

$mergeMap = [];
foreach ($array as $key => $value) {
    if (preg_match('/H\d+/', $value, $matches)) {
        $searchId = $matches[0];
        $mergeMap[$searchId][] = $key;
    }
}
$result = [];
foreach ($mergeMap as $key => $indexes) {
    $result[$key] = '';
    foreach ($indexes as $index) {
        $result[$key] .= $array[$index];
    }
}
print_r($result);

Tested here: https://3v4l.org/J15pG

That… looks remarkably like the original answer i came up with, with the double loops. Here’s the version of the second codeblock:

$final = array();
foreach ($input AS $string) {
   preg_match("#H\d+#",$string, $key);
   $final[$key[0]] = (isset($final[$key[0]])) ? $final[$key[0]]." + ".$string : $string;
}
1 Like

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.