-1

I have this array:

$flavours = array (
    0 => array(799390 => 'Banana',),
    1 => array(799391 => 'Chocolate',)
);

And now I inside a foreach looping a set from my database. I get 'Banana' from the database and I need the array to give me 799390.

I have tried:

‌‌array_search('Banana', $flavours); 

but it does not work unless I add:

‌‌array_search('Banana', $flavours[0]); 

But I cannot add [0] as I won't be able to tell in which position 'Banana' flavour is in the array.

Any solution apart from looping again inside a foreach??

Thanks a ton

Martijn
  • 15,791
  • 4
  • 36
  • 68
  • You have nested arrays which is causing the problem, can you show the part where you read it from the database as either - use a WHERE clause in your SQL to fetch the specific item or create a single array directly from the query results. – Nigel Ren Jul 06 '20 at 12:43
  • 1
    This structure with "array within array" makes searching more complicated than it needs to be. Is it possible to change it to a simple array? – Joni Jul 06 '20 at 12:43
  • 1
    There was a similar question yesterday. Maybe this will guide you to the solution: https://stackoverflow.com/a/62744239/8296334 – Philip Weinke Jul 06 '20 at 12:52
  • 1
    @PhilipWeinke using `array_filter()` will always process every item in the array, so even if it was the first item it could check 100's of elements. It works, but isn't very efficient. – Nigel Ren Jul 06 '20 at 12:55
  • That's right, @NigelRen – Philip Weinke Jul 06 '20 at 12:57
  • Is it possible that the phrase/word being searched for will be of a different case or will it always match? – Professor Abronsius Jul 06 '20 at 13:11
  • Does this answer your question? [PHP multidimensional array search by value](https://stackoverflow.com/questions/6661530/php-multidimensional-array-search-by-value) – Martijn Jul 06 '20 at 13:17

3 Answers3

0

First, we can use array_walk_recursive() to flatten your array, which just gets rid of your nested arrays.

Next, we use array_flip() to swap the keys/values in the flattened array. This makes it easier to grab the ID for a specific term.

<?php

$flavours = [
    [799390 => 'Banana'],
    [799391 => 'Chocolate']
];

//flatten array
//Produces: Array ( [799390] => Banana [799391] => Chocolate )
array_walk_recursive($flavours,
    function($v, $k) use (&$temp) { 
        $temp[$k] = $v; 
    }
);

//flip array. Swaps keys with values.
//Produces: Array ( [Banana] => 799390 [Chocolate] => 799391 )
$flavours = array_flip($temp);

Now you can get the ID pretty easily, such as $flavours['Banana'].


If you have a very very large array, this method may become slow. However, I tested this with 100,000 values on my cheap webhost, and ran this method a few times (20-25 times). It is finishing consistently at around (usually under) 0.1 milliseconds, which is about 0.0014 seconds.

GrumpyCrouton
  • 8,486
  • 7
  • 32
  • 71
  • 1
    Not per se bad, but be careful with this implementation. If you have a large array this could become slow, and then you have multiple 'Banana', you will only save the last one. – Martijn Jul 06 '20 at 13:19
  • @Martijn True but the ID for "banana" should theoretically always be the same, I would assume. – GrumpyCrouton Jul 06 '20 at 13:20
0

You can insert an if statement to set a condition for your loop as

foreach ($flavours as $key => $value) {
  if($key =  array_search('Banana', $value)){
   echo $key; 
 }
}

Output

799390
Kunal Raut
  • 2,495
  • 2
  • 9
  • 25
0

If the word being searched for is a different case many of the usual array methods will not work when trying to find the match, using preg_grep however will allow matches to be found in a case-insensitive manner.

function findflavour( $search, $haystack ){
    foreach( $haystack as $index => $arr ){
        $res=preg_grep( sprintf( '@%s@i', $search ), $arr );
        if( !empty( $res ) ) return array_search( array_values( $res )[0], $arr );
    }
    return false;
}



$search='BaNanA';
$flavours=array(
    array( 799390 => 'Banana' ),
    array( 799391 => 'Chocolate' ),
    array( 729361 => 'Chilli' ),
    array( 879695 => 'Apple' ),
    array( 995323 => 'Avacado' ),
    array( 528362 => 'Orange' ),
    array( 723371 => 'Cherry' ),
);


printf( 'Key:%s', findflavour( $search, $flavours ) );

If there might be multiple elements in the source array with the same value but different IDs a slightly different version of the findflavour function

function findflavour( $search, $haystack, $multiple=false ){
    $keys=[];
    foreach( $haystack as $index => $arr ){
        $res=preg_grep( sprintf( '@%s@i', $search ), $arr );
        if( !empty( $res ) ) {
            $key=array_search( array_values( $res )[0], $arr );
            if( $multiple )$keys[]=$key;
            else return $key;
        }
    }
    return $multiple ? $keys : false;
}


$multiple=true;
$search='AVacAdo';
$flavours=array(
    array( 799390 => 'Banana' ),
    array( 799391 => 'Chocolate' ),
    array( 291333 => 'Avacado' ),
    array( 729361 => 'Chilli' ),
    array( 879695 => 'Apple' ),
    array( 995323 => 'Avacado' ),
    array( 528362 => 'Orange' ),
    array( 723371 => 'Cherry' ),
);


printf( 'Key(s): %s', print_r( findflavour( $search, $flavours, $multiple ), true ) );
Professor Abronsius
  • 33,063
  • 5
  • 32
  • 46