1

Im working on a way to check if a array contains a value, if not dont run inner code. As the example below there are a couple of languages, but in this case the 'en' language is not present, so if the current translation is 'en' and the 'en' language is not present in the array dont run the second foreach. Using the in_array does not seem to work, if there a function to check if the the valeu is present in the childeren of an array?

the array

$arr =array(
    [16] => Array
        (
            [0] => Array
                (
                    [language] => de
                    [translation] => blog/beer
                )

            [2] => Array
                (
                    [language] => es
                    [translation] => 
                )

            [3] => Array
                (
                    [language] => fr
                    [translation] => blog/paris-big-city
                )

            [4] => Array
                (
                    [language] => it
                    [translation] => blog/it-slug
                )

            [5] => Array
                (
                    [language] => nl
                    [translation] => blog/nederlands-slug
                )

        )

        [...]//more
)

the loop

foreach($arr as $items){

    //we need to check if current language is present
    if( in_array('en' , $items) ){
        foreach($items as $item){

         // run code when certain language is present

        }
    }

}
user759235
  • 2,147
  • 3
  • 39
  • 77

3 Answers3

0

You can use array_walk_recursive. It will apply a function recursively to an array and sub-arrays.

Doc and example:

public function testArray()
{
    $arr = [
        16 => [
            1 => [
                'language'    => 'de',
                'translation' => 'blog/beer',
            ],
            2 => [
                'language'    => 'en',
                'translation' => 'url/url',
            ],
        ]
    ];

    $match = 'en';
    array_walk_recursive($arr, function ($key, $value) use ($match) {
        if ($key === $match) {
            // run code when certain language is present
            print "Gotcha \n";
            print $key . "\n";
            print $value . "\n";
        }
    });
}

The above example will output:

Gotcha 
en
language
Ollie in PGH
  • 2,559
  • 2
  • 16
  • 19
  • How does this answer the question? OP doesn't want to output the array. This is probably just copied from the manual, right? – Andreas Jan 30 '18 at 13:51
  • 1
    It is copied from the manual. The guy that answered even said so. But his answer is correct. It just needs adjusting to OPs needs. – Andrei Jan 30 '18 at 13:54
  • @Andrew OP wants to **not** loop if the value is not in the array, this just echos all values. – Andreas Jan 30 '18 at 14:00
  • @Andreas `You can use array_column to make the in_array work as you expect.` that's your answer. This is @ASOlivieri `You can use array_walk_recursive.`. If you want to criticize others, make sure your answers is properly written and fully explained. Both answers are correct. Literally both. – Andrei Jan 30 '18 at 14:01
  • It's not the same. Try them and you will see. Create an array and test the codes and you will see. Also on SO you are expected to write answers, not copy paste from manual and say the OP needs to correct it themselves. – Andreas Jan 30 '18 at 14:07
  • @Andrew got a chance to try it yet? – Andreas Jan 31 '18 at 12:06
  • @Andreas I posted another answer with ASOlivieri 's answer, but modified. – Andrei Jan 31 '18 at 12:55
  • I updated with my answer with an example very much like Andrew's only simplified a little further. – Ollie in PGH Jan 31 '18 at 13:32
0

Here's an approach using array_walk_recursive and a boolean flag to determine if a certain string exists as a value in an array of undetermined nesting and depth.

This solution simple, easy to read and most importantly scales very well since it doesn't matter how many nesting levels the array has.

$arr = [
  16 => [
      1 => [
          'language' => 'de',
          'translation' => 'blog/beer',
      ],
      2 => [
          'language' => 'en',
          'translation' => 'url/url',
      ],
  ]
];

$languageExists = false;
$match = 'en';
array_walk_recursive($arr, function ($key, $value) use (&$languageExists, $match) {
   if($key === $match) {
       $languageExists = true;
   }
});

foreach($arr as $items){
    //we need to check if current language is present
    if($languageExists) {
        foreach($items as $item){
            // run code when certain language is present
        }
    }
}
Andrei
  • 3,434
  • 5
  • 21
  • 44
  • This is a seriously bad solution. You run the complete array once just to find if "en" exists then loop it again. – Andreas Jan 31 '18 at 13:47
  • The point of this answer is to answer OPs question, thus I'm using parts of his code. Normally you'd do whatever you want to do in the `array_walk_recursive` part or don't use annonymous functions with it. If you want to cherry pick, I'm sure you can. Leaving that aside unless he's running arrays with thousand of entries this isn't even close to any sort of performance hindering. He could probably run another 10 foreaches one after the other and it wouldn't even matter – Andrei Jan 31 '18 at 14:00
  • That does not make any sense at all. OP asked for a solution to not loop an array twice, and your suggestion is to loop it once and then again. Do you not see the problem with that? – Andreas Jan 31 '18 at 14:51
-1

You can use array_column to make the in_array work as you expect.

$lang = array_column($arr, "language");
foreach($arr as $items){

    if( in_array('en', $lang) ){
        foreach($items as $item){

         // run code when certain language is present

        }
    }

}

Array_column grabs all languages in a separate array so that in_array can look in a single dimensional array as it's supposed to.
Multidimensional arrays does not work with in_array.

Edit, missplaced the array_column.

Andreas
  • 23,610
  • 6
  • 30
  • 62