I have a multidimensional array. They keys of the separate arrays are text. I would like to know how to match the key with part of a string that's from looped SELECT data.
Example of Array
Array ( [Volvo] => Array ( [0] => )
[Ford] => Array ( [0] => )
[Seat] => Array ( [0] => ) )
So from this array $cars, how would I be able to match data coming from my SELECT query
Select Output echo $row['car'];
Volvo, Mercedes, Lexus
What I'm after
if the key of one of my arrays matches part of the string from my select query, so as the example says above Volvo would match, then do something. That something for me is adding more data in that array.
I have tried variations of in_array, array_search and array_filter but have not found a solution that works for me.
Example of the reverse of what i was doing through a foreach loop
$searchword = $array_element;
$result = array_filter($cars, function($var) use ($searchword) { return preg_match("/\b$searchword\b/i", $var); });
taken from: Search for PHP array element containing string
This should work for you:
First I used preg_split() to split your search string (Volvo, Mercedes, Lexus) into an array.
The regex:
/\s*,\s*/
Simply means this:
\s* match any white space character [\r\n\t\f ]
Quantifier: * Between zero and unlimited times, as many times as possible, giving back as needed [greedy]
, matches the character , literally
\s* match any white space character [\r\n\t\f ]
Quantifier: * Between zero and unlimited times, as many times as possible, giving back as needed [greedy]
This makes sure we don't have spaces in the search words from your string. So with this we will end up with an array like this:
Array
(
[0] => Volvo
[1] => Mercedes
[2] => Lexus
)
After that I just take the array_intersect_key() from your array and the search array, which we just created.
Code:
<?php
$arr = preg_split("/\s*,\s*/", $row["car"], -1, PREG_SPLIT_NO_EMPTY);
if(($intersect = array_intersect_key($cars, array_flip($arr)))) {
echo "Do stuff!";
print_r($intersect);
} else {
echo "Drink a cup of tea";
}
?>
output:
Array
(
[Volvo] => Array
(
[0] =>
)
)
There are many ways to achieve your goal. I would use function explode() to split the data retrieved from the database ($row['car']) into pieces and trim() to be sure the identified pieces do not have padding spaces:
$brands = array_map('trim', explode(',', $row['car']));
Now, print_r($brands) should reveal an array whose values are candidate keys in your example array (called $example below).
Next it depends on what you want to match and how you want to process the matches.
A simple identification can be done using array_intersect() with $brands and the keys of the example array (see function array_keys()).
$common = array_intersect($brands, array_keys($example));
foreach ($common as $key) {
// Do something with $example[$key]
}
Or you can iterate directly over $brands and check if the value is a key in $example:
foreach ($brands as $key) {
if (array_key_exists($key, $example)) {
// Do something with $example[$key]
}
}
You can use isset($example[$key]) as well, instead of array_key_exists($key, $example]).
Try using PHP stripos, it's simple and effective:
Base data:
$array = Array ( [Volvo] => Array ( [0] => )
[Ford] => Array ( [0] => )
[Seat] => Array ( [0] => ) )
;
SQL data (string or array):
$row['car']; // string
$row //array of all SQL columns output
Foreach with stripos:
foreach($array as $rowKey=>$rowArray){
$rowKey = trim($rowKey);
foreach($row as $sqlRow=>$sqlArray){
$sqlRow = trim($sqlRow);
if (stripos($rowKey,$sqlRow) !== false){
///values are the same in this key in the array and in the SQL output
}
}
unset($sqlRow,$sqlArray);
}
unset($rowKey,$rowArray);
This may not be the most efficient but should give you the result you want
Related
Good day,
I have an I think rather odd question and I also do not really know how to ask this question.
I want to create a string variable that looks like this:
[car]Ford[/car]
[car]Dodge[/car]
[car]Chevrolet[/car]
[car]Corvette[/car]
[motorcycle]Yamaha[/motorcycle]
[motorcycle]Ducati[/motorcycle]
[motorcycle]Gilera[/motorcycle]
[motorcycle]Kawasaki[/motorcycle]
This should be processed and look like:
$variable = array(
'car' => array(
'Ford',
'Dodge',
'Chevrolet',
'Corvette'
),
'motorcycle' => array(
'Yamaha',
'Ducati',
'Gilera',
'Kawasaki'
)
);
Does anyone know how to do this?
And what is it called what I am trying to do?
I want to explode the string into the two arrays. If it is a sub array
or two individual arrays. I do not care. I can always combine the
latter if I wish so.
But from the above mentioned string to two arrays. That is what I
want.
Solution by Dlporter98
<?php
///######## GET THE STRING FILE OR DIRECT INPUT
// $str = file_get_contents('file.txt');
$str = '[car]Ford[/car]
[car]Dodge[/car]
[car]Chevrolet[/car]
[car]Corvette[/car]
[motorcycle]Yamaha[/motorcycle]
[motorcycle]Ducati[/motorcycle]
[motorcycle]Gilera[/motorcycle]
[motorcycle]Kawasaki[/motorcycle]';
$str = explode(PHP_EOL, $str);
$finalArray = [];
foreach($str as $item){
//Use preg_match to capture the pieces of the string we want using a regular expression.
//The first capture will grab the text of the tag itself.
//The second capture will grab the text between the opening and closing tag.
//The resulting captures are placed into the matches array.
preg_match("/\[(.*?)\](.*?)\[/", $item, $matches);
//Build the final array structure.
$finalArray[$matches[1]][] = $matches[2];
}
print_r($finalArray);
?>
This gives me the following array:
Array
(
[car] => Array
(
[0] => Ford
[1] => Dodge
[2] => Chevrolet
[3] => Corvette
)
[motorcycle] => Array
(
[0] => Yamaha
[1] => Ducati
[2] => Gilera
[3] => Kawasaki
)
)
The small change I had to make was:
Change
$finalArray[$matches[1]] = $matches[2]
To:
$finalArray[$matches[1]][] = $matches[2];
Thanks a million!!
There are many ways to convert the information in this string to an associative array.
split the string on the new line into an array using the explode function:
$str = "[car]Ford[/car]
[car]Dodge[/car]
[car]Chevrolet[/car]
[car]Corvette[/car]
[motorcycle]Yamaha[/motorcycle]
[motorcycle]Ducati[/motorcycle]
[motorcycle]Gilera[/motorcycle]
[motorcycle]Kawasaki[/motorcycle]";
$items = explode(PHP_EOL, $str);
At this point each delimited item is now an array entry.
Array
(
[0] => [car]Ford[/car]
[1] => [car]Dodge[/car]
[2] => [car]Chevrolet[/car]
[3] => [car]Corvette[/car]
[4] => [motorcycle]Yamaha[/motorcycle]
[5] => [motorcycle]Ducati[/motorcycle]
[6] => [motorcycle]Gilera[/motorcycle]
[7] => [motorcycle]Kawasaki[/motorcycle]
)
Next, loop over the array and pull out the appropriate pieces needed to build the final associative array using the preg_match function with a regular expression:
$finalArray = [];
foreach($items as $item)
{
//Use preg_match to capture the pieces of the string we want using a regular expression.
//The first capture will grab the text of the tag itself.
//The second capture will grab the text between the opening and closing tag.
//The resulting captures are placed into the matches array.
preg_match("/\[(.*?)\](.*?)\[/", $item, $matches);
//Build the final array structure.
$finalArray[$matches[1]] = $matches[2]
}
The following is an example of what will be found in the matches array for a given iteration of the foreach loop.
Array
(
[0] => [motorcycle]Gilera[
[1] => motorcycle
[2] => Gilera
)
Please note that I use the PHP_EOL constant to explode the initial string. This may not work if the string was pulled from a different operating system than the one you are running this code on. You may need to replace this with the actual end of line characters that is being used by the string.
Why don't you create two separate arrays?
$cars = array("Ford", "Dodge", "Chevrolet", "Corvette");
$motorcycle = array("Yamaha", "Ducati", "Gilera", "Kawasaki");
You could also use an Associative array to do this.
$variable = array("Ford"=>"car", "Yamaha"=>"motorbike");
In PHP, is there a function or anything else that will remove all elements in an array that do not match a regex.
My regex is this: preg_match('/^[a-z0-9\-]+$/i', $str)
My array's come in like this, from a form (they're tags actually)
Original array from form. Note: evil tags
$arr = array (
"french-cuisine",
"french-fries",
"snack-food",
"evil*tag!!",
"fast-food",
"more~evil*tags"
);
Cleaned array. Note, no evil tags
Array (
[0] => french-cuisine
[1] => french-fries
[2] => snack-food
[3] => fast-food
)
I currently do like this, but is there a better way? Without the loop maybe?
foreach($arr as $key => $value) {
if(!preg_match('/^[a-z0-9\-]+$/i', $value)) {
unset($arr[$key]);
}
}
print_r($arr);
You could use preg_grep() to filter the array entries that match the regular expression.
$cleaned = preg_grep('/^[a-z0-9-]+$/i', $arr);
print_r($cleaned);
Output
Array
(
[0] => french-cuisine
[1] => french-fries
[2] => snack-food
[4] => fast-food
)
I would not necessarily say it's any better per se, but using regexp and array_filter could look something like this:
$data = array_filter($arr , function ($item){
return preg_match('/^[a-z0-9\-]+$/i', $item);
});
Where we're returning the result of the preg_match which is either true/false. In this case, it should correctly remove the matched evil tags.
Here's your eval.in
I have a string in this form
$navigation="<li>A</li><li>B</li><li>C</li><li>A</li><li>B</li><li>C</li><li>A</li><li>B</li><li>C</li>";
The list is generated dynamically from database and hence the number of elements is not fixed. I want to split this list after every 5th element, so if there are 10 "<li></li>" elements in this string I should get two strings output1 and output2.
I have tried explode but it doesn't work as we have to impose restriction on nth element and I have also tried string_split but that is not working also.
So what is the solution?
Ahmar
You can do it this way:
$s = "<li>A</li><li>B</li><li>C</li><li>A</li><li>B</li><li>C</li><li>A</li><li>B</li><li>C</li>";
if (preg_match_all('~((?:<li>.*?</li>){5})~i', $s, $arr))
print_r($arr);
OUTPUT:
Array
(
[0] => Array
(
[0] => <li>A</li><li>B</li><li>C</li><li>A</li><li>B</li>
)
[1] => Array
(
[0] => <li>A</li><li>B</li><li>C</li><li>A</li><li>B</li>
)
)
The first array defines the current values:
Array ( [0] => schools [1] => high-wood [2] => students )
The second array is a map that is triggered by the first array and also hold the replacement keys:
Array ( [/schools/{school-name}/students/] => /{school-name}/students/ )
The idea is that the second segment of the array key holds the replacement key and the final returned array is the output map indicating the place of the replacement key.
The final desired output would then be:
/high-wood/students/
I am trying to find a generic solution to this that may have any number of incoming values, and any number of replacement keys in any position.
Here is an example of the generic incoming array:
Array ( [0] => param1 [1] => param2 [2] => key-value )
And the generic-ish map:
Array ( [/param1/param2/{key-map}/] => /{map-key}/anything/ )
The output of this would be:
/key-value/anything/
The basic idea is that the map-key is detected at the second segment (it could be anywhere), so that value is taken from the incoming array and put into the map-key holder of the output array.
Currently I have managed to make a vomitus array of foreach loops and preg_matches and I fear even presenting those would further confuse the issue.
Hmm...how about something like this. Untested:
$input = array('schools', 'high-wood', 'students');
// Here I'm making the blithe assumption that you can further tweak the URI map
$uriMap = array('^/schools/([^/]+)/students/$' => '/{school-name}/students/');
// ^ ^^^^^^^ ^
// anchor capturing group anchor
// Massage input to match format of $uriMap
$inUri = '/'.implode('/', $input).'/';
foreach($uriMap as $pattern => $target){
if(false !== preg_match($pattern, $inUri, $matches){
// $matches[1] should have the matched string
$mapped = str_replace('{school-name}', $matches[1], $target);
break;
}
}
echo $mapped;
/high-wood/students/
Cheers
I have an array that contains entries that themselves contain two types of entries.
For simplicity sake, let's say that the entries are like this:
a|1
b|4
a|2
c|5
b|3
etc.
In fact they represent categories and subcategories in my database.
I will use explode to break these entries into letters and digits.
The question is: I want to group them by category.
What's the easiest way to create a multilevel array, which could be sorted by letters:
a|1
a|2
b|4
b|3
c|5
?
How about something like this?
$input = array('a|1','b|4','a|2','c|5','b|3');
$output = array();
foreach($input as $i){
list($key,$val) = explode("|",$i);
$output[$key][] = $val;
}
Output:
Array
(
[a] => Array
(
[0] => 1
[1] => 2
)
[b] => Array
(
[0] => 4
[1] => 3
)
[c] => Array
(
[0] => 5
)
)
<?php
$your_array = array();
$your_array[a] = array('1','2','3');
$your_array[b] = array('4','5','6');
print_r($your_array);
?>
I take it that your entries are strings (relying on the fact that you want to use explode() on them).
If so you can simply sort the array by using sort($array), and then iterate on that array and explode the values and put them in another array, which will be sorted by the previous array's order.