-1

I have a PHP variable like:

$genre = 'crime / thriller / mystery / adventure';

I use the following piece of code to convert it to an array of genres:

$return['movie_genre'] = array_map('trim', explode('/', $genre));

I also have another reference array, like:

$references = array(
    'crime' => 9896,
    'biography' => 9898,
    'western' => 9899,
    'drama' => 9901,
    'action' => 9902,
    'news' => 9903,
    'sci-fi' => 9904,
    'thriller' => 9906,
    'history' => 9907,
    'animation' => 9909,
    'comedy' => 9910,
    'musical' => 9911,
    'music' => 9912,
    'mystery' => 9913,
    'documentary' => 9914,
    'family' => 9915,
    'adventure' => 9916,
    'war' => 9917,
    'reality-tv' => 9919,
    'romance' => 9920,
    'sport' => 9921,
    'game-show' => 9922,
    'talk-show' => 9923,
    'horror' => 9924,
    'fantasy' => 9925,
    'film-noir' => 9926,
);

, where I'd like to lookup the textual values of the first array, and replace them with their numerical references of the reference array, ending up to something like this (for the above example):

[movie_genre] => Array
    (
        [0] => 9896
        [1] => 9906
        [2] => 9913
        [3] => 9916
    )

Let me be clear, I'm not looking for a foreach solution. That one, I can write myself. I'm looking for an elegant one-liner, like another array_map, or array_walk; ideally if I could combine it with the one-liner I already use to create the array itself from the initial string variable. But I can't thing of anything elegant... Any help would be much appreciated. TIA.

1
  • 1
    Some people value performance and maintainability over clever one-liners. ¯\_(ツ)_/¯ Commented May 25, 2021 at 21:03

2 Answers 2

2

Utilizing array_map and arrow functions:

$result = array_map(fn ($genre) => $references[$genre], $return['movie_genre']);

Note that for versions prior to 7.4, when arrow functions were introduced, you'd have to write an anonymous function:

$result = array_map(function ($genre) use ($references) {
    return $references[$genre];
}, $return['movie_genre']);

You can easily substitute $return['movie_genre'] with your existing one liner.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a lot for your reply. Indeed it does what I asked for, so for that it deserves a thumb up, but for some reason I tend to like the other reply more, that's why I marked it as the accepted answer for my question!
1

Just flip the array of genres and compute the intersection of the keys. With your current code:

$return['movie_genre'] = array_intersect_key($references,
                             array_flip($return['movie_genre']));

Or combined:

$return['movie_genre']= array_intersect_key($references,
                            array_flip(array_map('trim', explode('/', $genre))));

If you really need those integer keys:

$return['movie_genre']= array_values(array_intersect_key($references,
                            array_flip(array_map('trim', explode('/', $genre)))));

Or to combine with your array_map to lookup the reference key from the value:

 $return['movie_genre'] = array_map(function($v) use($references) {
                                        return $references[trim($v)];
                                    }, explode('/', $genre));

And for fun with your current code; flip the reference array and grep for the genres and get the keys:

$return['movie_genre'] = array_keys(
                         preg_grep('/^'.implode('|', $return['movie_genre']).'$/',
                         array_flip($references)));

All that being said, I would probably do this:

foreach(array_map('trim', explode('/', $genre)) as $v) {
    $return['movie_genre'][] = $references[$v]; // or trim() here instead
}

3 Comments

That was exactly what I was looking for, and didn't have the clear mind or inspiration to do it myself! Thanks a TON!
Out of curiosity, which one did you use?
I used this: array_values(array_intersect_key($genres, array_flip($return['movie_genre'])))

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.