3
\$\begingroup\$

I have to find where a given string is in my multidimensional array. So this is my array

$input = array(array('time' => '18:31:00', 'artist' => 'LUIS RODRIGUEZ & DEN HARROW'), array('time' => '18:32:00', 'artist' => 'J BALVIN'), array('time' => '18:33:00', 'artist' => 'THE BLACK EYED PEAS FT J BALVIN'), array('time' => '18:34:00', 'artist' => 'THE BLACK EYED PEAS FT J BALVIN'), array('time' => '18:35:00', 'artist' => 'J BALVIN'));

I have to find at what time I can find this

$artista_inserito = 'THE BLACK EYED PEAS FT J BALVIN';

So I use a function to delimiter my array and even string

function multiexplode($delimiters, $string)
{

    $ready = str_replace($delimiters, $delimiters[0], $string);
    $launch = explode($delimiters[0], $ready);
    return  $launch;
}

// array with string delimeter
$array_delimiter_artisti = array(' FEAT ', ' feat ', ' FT ', ' ft ', ' + ', ' AND ', ' and ', ' E ', ' e ', ' VS ', ' vs ', ' FEAT. ', ' feat. ', ' FT. ', ' ft. ', ' VS. ', ' vs. ', ' , ', ' & ');

// I split the current artist
$artisti_inseriti = multiexplode($array_delimiter_artisti, $artista_inserito);

So I search the given string un my array

foreach ($input as $split) {
    $time = $split['time'];
    $artist = $split['artist'];
    $lista_artisti = multiexplode($array_delimiter_artisti, $artist);

    foreach ($lista_artisti as $nuovo) {
        $artista_split = $nuovo;

        // copy all new data in new array
        $nuovo_array_dati[] = array('time' => $time, 'artist' => $artista_split);
    }
}

foreach ($nuovo_array_dati as $controllo) {
    $time = $controllo['time'];
    $artist = $controllo['artist'];

    foreach ($artisti_inseriti as $trova_artista) {
        $artista_singolo = $trova_artista;



        foreach ($controllo as $index => $a) {
            if (strstr($a, $artista_singolo)) {
                // now I can print where I found the given string $artista_inserito
                echo "$artista_singolo  is at $time ";

            }
        }
    }
}

So this is my output

J BALVIN is at 18:32:00 
THE BLACK EYED PEAS is at 18:33:00 
J BALVIN is at 18:33:00 
THE BLACK EYED PEAS is at 18:34:00 
J BALVIN is at 18:34:00 
J BALVIN is at 18:35:00 

Can I improve this? Thanks

\$\endgroup\$
3
  • \$\begingroup\$ Merely splitting on whitespaces may not be a reliable way to search the haystacks with the generated needles. I feel like this topic has been reviewed before. codereview.stackexchange.com/q/178870/141885 Also, according to the php documentation, it is not advised to use strstr() to check the existence of a substring in a string -- using strpos() is a better performer. I don't see any reason to check the time column's data. Why do you only use the first element of $array_delimiter_artisti? \$\endgroup\$ Commented Apr 8, 2020 at 0:09
  • 1
    \$\begingroup\$ @mickmackusa Please don't use duplicates like this on Code Review. Our policy on duplicates is a bit different from other Q&A sites. \$\endgroup\$ Commented Apr 8, 2020 at 7:20
  • \$\begingroup\$ @mickmackusa I have to log at what time there is the same artist, so I have to check also the time \$\endgroup\$ Commented Apr 8, 2020 at 8:46

1 Answer 1

2
\$\begingroup\$

I have a bias toward regex because I'm generally comfortable with most techniques, so I'll recommend condensing your array of delimiters into a single regex pattern and employ preg_split() to execute the explosion.

After splitting the search string into its separate artists, I am flipping the values & keys to optimize the lookup for later use in the nested loop.

Then as you iterate the haystack of artist times, you can re-use the splitting pattern, then iterate each individual artist and store the desired data for qualifying rows.

Code: (Demo)

$fullArtistTimes = [
    ['time' => '18:31:00', 'artist' => 'LUIS RODRIGUEZ & DEN HARROW'],
    ['time' => '18:32:00', 'artist' => 'J BALVIN'],
    ['time' => '18:33:00', 'artist' => 'THE BLACK EYED PEAS FT J BALVIN'],
    ['time' => '18:34:00', 'artist' => 'THE BLACK EYED PEAS FT J BALVIN'],
    ['time' => '18:35:00', 'artist' => 'J BALVIN']
];

$fullArtist = 'THE BLACK EYED PEAS FT J BALVIN';

$artistDelimiters = '~ (?:[+e,&]|and|f(?:ea)?t\.?|vs\.?) ~i';

$artists = array_flip(preg_split($artistDelimiters, $fullArtist));

$result = [];
foreach ($fullArtistTimes as $row) {
    foreach (preg_split($artistDelimiters, $row['artist']) as $artist) {
        if (isset($artists[$artist])) {
            $result[] = "{$artist} is at {$row['time']}";
        }
    }
}

var_export($result);

Output:

array (
  0 => 'J BALVIN is at 18:32:00',
  1 => 'THE BLACK EYED PEAS is at 18:33:00',
  2 => 'J BALVIN is at 18:33:00',
  3 => 'THE BLACK EYED PEAS is at 18:34:00',
  4 => 'J BALVIN is at 18:34:00',
  5 => 'J BALVIN is at 18:35:00',
)

If this does not work for all of your cases, then I would need to see more test cases and your desired result before I could properly adjust my snippet.

\$\endgroup\$
6
  • \$\begingroup\$ Thanks, my only problem is the $artistDelimiters, I have to retrieve the delimiters from a mysql table where the user can add or remove some words, so the delimiters has to be more simple \$\endgroup\$ Commented Apr 8, 2020 at 16:00
  • \$\begingroup\$ '~ (?:' . implode('|', array_map(function($v){ return preg_quote($v, '~'); }, $databaseDelimiters)) . ') ~' \$\endgroup\$ Commented Apr 8, 2020 at 20:34
  • \$\begingroup\$ If I use this I haven't same result code $databaseDelimiters = array(' FEAT ', ' feat ', ' FT ', ' ft ', ' + ', ' AND ', ' and ', ' E ', ' e ', ' VS ', ' vs ', ' FEAT. ', ' feat. ', ' FT. ', ' ft. ', ' VS. ', ' vs. ', ' , ', ' & '); $artistDelimiters = '~ (?:' . implode('|', array_map(function ($v) { return preg_quote($v, '~'); }, $databaseDelimiters)) . ') ~'; $artists = array_flip(preg_split($artistDelimiters, $fullArtist)); \$\endgroup\$ Commented Apr 8, 2020 at 22:04
  • \$\begingroup\$ I'm sorry, I have to delete the blank spaces... it is right? Thanks \$\endgroup\$ Commented Apr 8, 2020 at 22:13
  • \$\begingroup\$ Ah yes, I forgot that bit. Yes, trim() them (before even saving them to the db -- keep your data tidy). \$\endgroup\$ Commented Apr 8, 2020 at 22:24

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.