Like array_search, but searches a full string
<?php
function array_searchstring( $needle, $haystack, $valueAsNeedle = FALSE ){
foreach( $haystack as $key => $value ){
$needleValue = $needle;
if($valueAsNeedle){
list( $value, $needleValue ) = array( $needleValue, $value ); // swap values
}
if( stripos( $value, $needleValue ) !== FALSE ) {
return $key;
}
}
return FALSE;
}
I needed array_search()
to do a search using the values of my haystack as needles against the needle parameter so I created array_searchstring()
. This behavior set by the $valueAsNeedle parameter. By default the array_searchstring()
function does a complete string search instead of an exact match which is what array_search()
does.
I had a list of school names and for each school name I wanted to say we're servicing grades A to B. Here it is in practice:
<?php
function array_searchstring( $needle, $haystack, $valueAsNeedle = FALSE ){
foreach( $haystack as $key => $value ){
$needleValue = $needle;
if($valueAsNeedle){
list( $value, $needleValue ) = array( $needleValue, $value ); // swap values
}
if( stripos( $value, $needleValue ) !== FALSE ) {
return $key;
}
}
return FALSE;
}
$schools = array( "Cougar Elementary School", "Eagle Middle School", "Owl High School");
$gradeMapping = array(
'4-5' => 'elementary',
'6-8' => 'middle',
'9-12' => 'high',
);
$buffer = array();
$key = array_search( "elementary", $gradeMapping );
var_dump( 'key', $key );
foreach( $schools as $school ){
$buffer[] = array( 'title' => $school, 'gradesServiced' => array_searchstring( $school, $gradeMapping, TRUE ) );
}
print_r( $buffer );
/*
Array
(
[0] => Array
(
[title] => Cougar Elementary School
[gradesServiced] => 4-5
)
[1] => Array
(
[title] => Eagle Middle School
[gradesServiced] => 6-8
)
[2] => Array
(
[title] => Owl High School
[gradesServiced] => 9-12
)
)
*/
Because Unit Test
<?php
function array_searchstring( $needle, $haystack, $valueAsNeedle = FALSE ){
foreach( $haystack as $key => $value ){
$needleValue = $needle;
if($valueAsNeedle){
list( $value, $needleValue ) = array( $needleValue, $value ); // swap values
}
if( stripos( $value, $needleValue ) !== FALSE ) {
return $key;
}
}
return FALSE;
}
class ArraySearchStringTest extends PHPUnit_Framework_TestCase {
protected $needleAsValueHaystack;
protected $haystack;
public function setUp( ){
$this->needleAsValueHaystack = array(
'4-5' => 'elementary',
'6-8' => 'middle',
'9-12' => 'high',
);
$this->haystack = array(
'4-5' => 'Orange Elementary School',
'6-8' => 'Waterside Middle School',
'9-12' => 'Waterloo High School',
);
}
/**
* @dataProvider assertFalseProvider
*/
public function test_search_returnsFalse( $needle )
{
$this->assertFalse( array_searchstring( $needle, $this->needleAsValueHaystack, TRUE ));
$this->assertFalse( array_searchstring( $needle, $this->haystack ));
}
/**
* @dataProvider assertEqualsProvider
*/
public function test_search_returnsCorrectKeys($key, $value)
{
$this->assertEquals( $key, array_searchstring( $value, $this->needleAsValueHaystack, TRUE ));
$this->assertEquals( $key, array_searchstring( $value, $this->haystack ));
}
public function test_searchExactMatch_returnsCorrectKeys()
{
$text = 'Waterloo High School';
$this->assertEquals( '9-12', array_searchstring( $text, $this->haystack ));
}
public function assertFalseProvider()
{
return array(
array( 'Technical School' )
);
}
public function assertEqualsProvider()
{
return array(
array( '4-5', 'elementary school' ),
array( '6-8', 'middle school' ),
array( '9-12', 'high school' ),
);
}
}
Written by Jorge Colon
Related protips
2 Responses
I think your stripos( $needle, $value ) variables are reversed.
@rob%20malon I programmed it for a specific use case which worked, but I refactored it to separate my particular use case from the default behavior. It should work now the way you would expect it to work. Have a look at the latest version.
Seems like I can't mention your name since it has a space in it. :/