Jump to content

Recommended Posts

I have a array of file path strings and trying to search the array for a string that would be the end of the path sting and return the index of the file path that contains the string. I've tried using something like this, but it finds the keyword in anyplace in the file path. I've also tried strripos() as well with the same results. Any suggestions?

function array_search_partial($arr, $keyword) {
    foreach ($arr as $index => $string) {
			if(strpos($string, $keyword) !== FALSE) {
				return $index;
			}
    }
}

 

Link to comment
https://forums.phpfreaks.com/topic/309328-searching-array-for-partial-exact-match/
Share on other sites

Hmm. Doesn't sound like what you were describing in your first post.

If the pattern is something-something-username, and the username doesn't itself contain hyphens, then you need to find the portion of the string after the last hyphen.

I believe I've got it! Does this seem correct to you?

function array_search_partial($arr, $keyword) {
    foreach ($arr as $index => $string) {
			$userBase = basename($string);
			$test = substr_count($userBase, '-');
			if($test === 2) {
				if(preg_split("/[-]+/", $userBase)[2] == $keyword) {
					return $index;
				}
			}
    }
}

 

According to your first post you have an array of paths/filenames EG

$arr = [
        'xxx/yyy/aaa-bbb-xxx.txt',
        'xxx/yyy/aaa-vcf.txt',
        'xxx/yyy/aaa-bbb-vbn.txt',
        'xxx/yyy/aaa-bbb-vvv.txt',
        'xxx/yyy/aaa-bbb-vcf.txt',
        'xxx/yyy/aaa-bbb-xcv.txt'
        ];

If that is the case, I think your preg_split line needs to add a "." so the file extension is excluded. I.E.

if(preg_split("/[-.]+/", $userBase)[2] == $keyword)
                  ^

then

echo array_search_partial($arr, 'vcf');                   //-->   4

Also, your function should return something (false ?) if no match is found.

Edited by Barand
  • Like 1

Something like this could get your started

<?php
$filepaths = array();
$filepaths[] = "/path/to/file/bob-villa-bvilla35";
$filepaths[] = "/path/to/file/jim-bob-dinosaur64";
$filepaths[] = "/path/to/file/abe-lincoln-alinkler";
$filepaths[] = "/path/to/file/michael-jordan-ncairman";
$filepaths[] = "/path/to/file/bart-simpson-eatmyshorts";

$s = "air";
$regex = "#\/path\/to\/file\/([^$]+)#";
$userregex = "#^\w+-\w+-(.*".$s.".*)$#";

$userKey = array_filter($filepaths, function($e) use ($s,$regex,$userregex){
        $userString = preg_match($regex, $e, $m);
        $user = preg_match($userregex, $m[1], $o);
        if(count($o)) return strpos($o[1],$s)+1; 
});

$key = key($userKey);
echo "The key is: " . $key . "<br>" . $filepaths[$key];

?>

That would give you

Quote

The key is: 3
/path/to/file/michael-jordan-ncairman

 

One question though, why would I need to return "false" if nothing is found? It will always find something. And when I've tried adding it as below it doesn't return the correct results. (Also, to make this clear the file paths in the array don't contain the extension.)

function array_search_partial($arr, $keyword) {
    foreach ($arr as $index => $string) {
			$userBase = basename($string);
			$test = substr_count($userBase, '-');
			if($test === 2) {
				if(preg_split("/[-]+/", $userBase)[2] == $keyword) {
					return $index;
				} else {
				return false;
			}
		}	
}

 

Do you test your code? Aside from the logic being wrong it is also missing a "}"

In the code below using your function, a search for "dinosaur64"" should return "1"

$filepaths = array();
$filepaths[] = "/path/to/file/bob-villa-bvilla35";
$filepaths[] = "/path/to/file/jim-bob-dinosaur64";
$filepaths[] = "/path/to/file/abe-lincoln-alinkler";
$filepaths[] = "/path/to/file/michael-jordan-ncairman";
$filepaths[] = "/path/to/file/bart-simpson-eatmyshorts";

function array_search_partial($arr, $keyword) {
    foreach ($arr as $index => $string) {
            $userBase = basename($string);
            $test = substr_count($userBase, '-');
            if($test === 2) {
                if(preg_split("/[-]+/", $userBase)[2] == $keyword) {
                    return $index;
                } else {
                    return false;
                }
            }
    }    
}

$index = array_search_partial($filepaths, 'dinosaur64');
var_dump($index);                                               //-->   bool(false)           (Should be "1")

 

27 minutes ago, nephesh said:

It will always find something.

You can guarantee that no-one will search for a keyword that isn't there?

(At the moment it will only ever find the first item.)

Edited by Barand

Yes, I tested my code. I am sorry, I had just added in the else statement for this post, as I have it working correctly as this:

function array_search_partial($arr, $keyword) {
    foreach ($arr as $index => $string) {
			$userBase = basename($string);
			$test = substr_count($userBase, '-');
			if($test === 2) {
				if(preg_split("/[-]+/", $userBase)[2] == $keyword) {
					return $index;
				} 
			}
		}	
}

It only needs to find one item, as the $keyword is a unique identifier. But you are right I should return false to the caller. Which is :

$index = array_search_partial($profilePaths, $userName);
      if($index){ 
          $profileLink = "/".$profilePaths[$index].".html";
      } 

 

I changed to function below so it returns "false" if the keyword is not found. 

If the matched item is the first in the array its index will be "0" so your test for 

if ($index)

will fail as 0 evaluates to false. You need to explicitly test for a Boolean false as below

function array_search_partial($arr, $keyword) {
    foreach ($arr as $index => $string) {
            $userBase = basename($string);
            $test = substr_count($userBase, '-');
            if($test === 2) {
                if(preg_split("/[-]+/", $userBase)[2] == $keyword) {
                    return $index;
                } 
            }
    }
    // if we get here it hasn't found the keyword
    return false;    
}

$index = array_search_partial($profilePaths, $userName);
if($index !== false){                                           // check it isn't (boolean) false
    $profileLink = "/".$profilePaths[$index].".html";
} 

 

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.