Search comma separated string

I have an array of company names, with a comma separated list of keywords. I’m trying to get it to print out “Nike” and “Patagonia” when the array is searched for “clothing”

$a=array(
    "Nike"=>"sports, clothing",
    "Ford"=>"cars, outdoors",
    "Patagonia"=>"clothing, outdoors"
);

echo array_search("clothing",$a); // should output Nike and Patagonia


Any ideas?

Try

  1. create an empty $result array
  2. Use foreach(…) on the $a array
  3. test each array loop element using str_pos()
  4. Append to $result if str_pos(…) Is true

Read the Php manual and beware of false negatives where the search string is the first element in the array loop element. Also beware of case sensitivity.

There may be more succinct solutions that others can suggest.

i would prefer using array_filter with a closure that uses a seperator and searchstring and takes every item to explode and check with in_array - that’s about 3 lines of code.

That’s not how array_search() works:

http://php.net/manual/en/function.array-search.php

Try this:

<?php 
  $haystack = array
  (
    "Nike"      => "sports, clothing",
    "Ford"      => "cars, outdoors",
    "Patagonia" => "clothing, outdoors"
  );

  $result = array();
  foreach( $haystack as $id => $item ):
    if( FALSE===strpos( $item, 'clothing' ) ):
      // 
    else:  
      $result[] = $item;
    endif;  
  endforeach;

  fred($haystack, '$haystack');

  fred($result, '$result');

  # echo array_search("clothing", $a); // should output Nike and Patagonia



//=======================================
function fred($value='yes we have no $val', $title='NO title???')
{
  $style  = 'width:88%; margin:2em auto;' 
          . 'border:solid 1px #aaa; padding: 0.42em;'
          ;

  echo '<pre style="' .$style .'">'; 
    echo '$title => ' .$title;
    echo '<br>';
    echo '$value => ';  //  .gettype($val);
    print_r($value); 
  echo '</pre>'; 
}


**Results:** > $title => $haystack $value => Array ( [Nike] => sports, clothing [Ford] => cars, outdoors [Patagonia] => clothing, outdoors )

$title => $result
$value => Array
(
[0] => sports, clothing
[1] => clothing, outdoors
)


to quote a knowledgeable user, **"First make it work, then make it better"** :)

Try your algorithm for this input:

$haystack = array
(
"Nike"      => "tv, soap opera",
"Ford"      => "cars, tv shows",
"Patagonia" => "clothing, outdoors, opera"
);

and then search for opera and tv :wink:

Seems OK to me?

Let me know the results:

<?php 
  $haystack = array
  (
    "Nike"      => "sports, clothing",
    "Ford"      => "cars, outdoors",
    "Patagonia" => "clothing, outdoors"
  );

$haystack = array
(
"Nike"      => "tv, soap opera",
"Ford"      => "cars, tv shows",
"Patagonia" => "clothing, outdoors, opera"
);

 $search = 'tv';
 $search = 'opera';
 $search = 'clothing';

  $search = $_GET['search'] ?? 'clothing';
  $result = array();
  foreach( $haystack as $id => $item ):
    if( FALSE===strpos( $item, $search ) ):
      // 
    else:  
      $result[] = $item;
    endif;  
  endforeach;

$tmp = <<< ____TMP

    <a href="?search=clothing"> clothing </a>

    <a href="?search=opera"> opera </a>$title => NO title???
$value => 
     clothing 

     opera 

     tv 
$title => $haystack
$value => Array
(
    [Nike] => tv, soap opera
    [Ford] => cars, tv shows
    [Patagonia] => clothing, outdoors, opera
)
$title => Search for: opera
$value => Array
(
    [0] => tv, soap opera
    [1] => clothing, outdoors, opera
)

    <a href="?search=tv"> tv </a>
____TMP;

  fred($tmp);
  fred($haystack, '$haystack');
  fred($result,  'Search for: ' .$search);

  # echo array_search("clothing", $a); // should output Nike and Patagonia


//=======================================
function fred($value='yes we have no $val', $title='NO title???')
{
  $style  = 'width:88%; margin:2em auto;' $title => NO title???
$value => 
     clothing 

     opera 

     tv 
$title => $haystack
$value => Array
(
    [Nike] => tv, soap opera
    [Ford] => cars, tv shows
    [Patagonia] => clothing, outdoors, opera
)
$title => Search for: opera
$value => Array
(
    [0] => tv, soap opera
    [1] => clothing, outdoors, opera
)
          . 'border:solid 1px #aaa; padding: 0.42em;'
          ;

  echo '<pre style="' .$style .'">'; 
    echo '$title => ' .$title;
    echo '<br>';
    echo '$value => ';  //  .gettype($val);
    print_r($value); 
  echo '</pre>'; 
}


**Output:** > $title => NO title??? $value => > clothing > > opera > > tv
> $title => $haystack $value => Array ( [Nike] => tv, soap opera [Ford] => cars, tv shows [Patagonia] => clothing, outdoors, opera )
> > $title => Search for: opera $value => Array ( [0] => tv, soap opera [1] => clothing, outdoors, opera )

I tried to hint you that search for “opera” will give you a false positive for Nike, which is a quite common mistake.
Given we have comma separated values, we are searching for entire values, not a substring that may be a part of a wrong value.

depends, i think the initial requirement is pretty unclear about how ‘likely’ the algo should be.

If the reason for this is that the keywords are stored in the database as a comma-separated string, then it illustrates why that is a poor database design, and how much easier it would be to select them if it were properly normalised.

1 Like

That’s but an excuse. If you read the spec carefully, and want to do your job the way it wont take you another rewrite, the requirement is pretty clear. Partial match is a different story and it wasn’t mentioned. Having “vicars” and “scars” found for the keyword “cars” can be desirable only by a lazy programmer, not willing to admit his mistake.

Exact match is a different story and it wasn’t mentioned

given the example, it was the desired option.

I read the original request as keywords and not word strings. The simple solution supplied satisfied the condition.

Hopefully when the original poster returns the raised presumptions can be clarified.

1 Like

Guys, no need for dispute if we don’t really know how exact the search is supposed to be!

So for completeness sake, here is my version of a simple exact match for a keyword :smiley:

function keyword_search($keyword, $array) {
	$result = [];
	
	foreach ($array as $key => $keywords) {
		if (in_array($keyword, preg_split('/[, ]+/', $keywords))) {
			$result[] = $key;
		}
	}
	
	return $result;
}


$a=array(
    "Nike"=>"sports, clothing",
    "Ford"=>"cars, outdoors",
    "Patagonia"=>"clothing, outdoors"
);

$result = keyword_search("clothing", $a); // should output Nike and Patagonia
print_r($result);
2 Likes

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