PHP return value within array - php

I am trying to retrieve all the first objects from an array, this is how my array looks like:
Array
(
[0] => lorem;1;banana
[1] => ipsum;2;apple
[2] => dolor;3;grapefruit
[3] => sit;4;pineapple;
[4] => amet;5;orange
)
I want it to return a certain value of that and store it in a variable, so that I can get all the fruit names, for example. Any way to do this?

You can use array_map:
$fruits = array_map(function($item) {
$arr = explode(';', $item);
return $arr[2];
}, $array);
var_dump($fruits);

Assuming the fruits always come last and may or may not have a trailing semicolon, you can use
preg_replace — Perform a regular expression search and replace
Example:
$data = [
'lorem;1;banana',
'ipsum;2;apple',
'dolor;3;grapefruit',
'sit;4;pineapple;',
'amet;5;orange'
];
$fruits = preg_replace('#.+;(.+?)[;]*$#', "$1", $data);
print_r($fruits);
The pattern means match everything up and including to a semicolon (greedy), then capture the content up to the end ending with or without a semicolon.
Output:
Array
(
[0] => banana
[1] => apple
[2] => grapefruit
[3] => pineapple
[4] => orange
)

You can use array_walk_recursive function and change your array item as per requirement.
use following code which will give you appropriate output:
$test = array(0 => 'lorem;1;banana', 1 => 'ipsum;2;apple', 2 => 'dolor;3;grapefruit',3 => 'sit;4;pineapple;',4 => 'amet;5;orange');
array_walk_recursive($test, 'test');
function test(&$item, $key)
{
$itemArray = explode(';', $item);
$item = $itemArray[2];
}

For the sake of completeness, those strings can be easily parsed as csv with str_getcsv
$a = array(
'lorem;1;banana',
'ipsum;2;apple',
'dolor;3;grapefruit',
'sit;4;pineapple;',
'amet;5;orange'
);
foreach($a as $line){
$csvString = str_getcsv($line,';');
$fruits[] = $csvString[2];
}
print_r($fruits);
Will output
Array
(
[0] => banana
[1] => apple
[2] => grapefruit
[3] => pineapple
[4] => orange
)

Related

Use array_column in combination with preg_match

Lets suppose we have an array of arrays that needs to be converted to rows
From this:
Array
(
[subject] => Array
(
[0] => EDN:LOC:DERR
[1] => EDN:LOC:DOXX
[2] => EDN:LOC:NTTT
[3] => EDN:LOC:NAGA
)
[object] => Array
(
[0] => ABS:D01::ADFPAZ01
[1] => ABS:D01::DOXYWITX
[2] => ABS:D01::NAGBAAD2
[3] => ABS:D01::NAGGAAD2
)
[units] => Array
(
[0] => ABS:D06::UNAA
[1] => ABS:D06::UMMM
[2] => ABS:D06::UPOP
[3] => ABS:D06::UPOP
)
To this:
[0] => "'DERR' , 'ADFPAZ01' , 'UNAA'"
[1] => "'DOXX' , 'DOXYWITX' , 'UMMM'"
[2] => "'NTTT' , 'NAGBAAD2' , 'UPOP'"
[3] => "'NAGA' , 'NAGGAAD2' , 'UPOP'"
So I need the arrays to be cleaned by a pattern and compressed into lines.
I managed the compact view with the following function
$array_res = array();
for ($i=0; $i<=$totalEntries-1; $i++) {
array_push($array_res, implode("', '", array_column($array_of_arrays, $i)));
}
My regex pattern is $pattern = '([^.:]*$)'; And it collects a sequence of letters from the end of the string until it finds a colon. And I used preg_match($pattern, $string, $match) to receive the proper string into the $match variable.
However, I cannot combine the above two procedures either with array_filter or array_map inside the for loop.
EDIT: Note that there can be a subarray that contains values without a colon. In that case we have to get the value as is
[units] => Array
(
[0] => NULL
[1] => VALUE1
[2] => VALUE2
[3] => NULL
)
Rather than using a regex, this just uses array_walk() to process the extracted column and for each item it uses strrchr() with : as the last character to match (although it will include the :, so uses substr() to remove the first char)...
for ($i=0; $i<=$totalEntries-1; $i++) {
$newRow = array_column($array_of_arrays, $i);
array_walk($newRow, function (&$data) {
$data = substr(strrchr(":".$data, ":") , 1);
});
$array_res[] = "'".implode("', '", $newRow)."'";
}
The part ":".$data deals with the time when there is no : in the string, it will always ensure that it does find something to use.
Other way:
$arr = [
'subject' => [ 'EDN:LOC:DERR', 'EDN:LOC:DOXX', 'EDN:LOC:NTTT', 'EDN:LOC:NAGA' ],
'object' => [ 'ABS:D01::ADFPAZ01', 'ABS:D01::DOXYWITX', 'ABS:D01::NAGBAAD2', 'ABS:D01::NAGGAAD2' ],
'units' => [ 'ABS:D06::UNAA', 'ABS:D06::UMMM', 'ABS:D06::UPOP', 'ABS:D06::UPOP' ]
];
$res = [];
$fmt = "'%s', '%s', '%s'";
foreach ($arr['subject'] as $k => $v) {
$res[] = vsprintf($fmt, preg_replace('~^.*:~', '', array_column($arr, $k)));
}
print_r($res);
Notice: If you don't know in advance your array length, nothing forbids to build the format pattern dynamically (using str_repeat or implode).

PHP: combine several arrays in associative one

I have this arrays:
$main = array("Name","Age");
$fname =array("Peter","Ben","Joe");
$age = array("35","37","43");
I need to combine it. Output array must be:
[0] =>
[Name] => [Peter]
[Age] => [35]
[1] =>
[Name] => [Ben]
[Age] => [37]
[2] =>
[Name] => [Joe]
[Age] => [43]
And so on. I have tried array_combine, but it gives an error, cuz $main contains only two values, array_merge combine arrays not exactly i want, it adds any next array to the end of result array.
How to solve my issue? Help , please!
Something like this should do:
$result = array_map(
function () use ($main) {
return array_combine($main, func_get_args());
},
$fname,
$age
);
PHP 5.6+ allows this nicer syntax for the callback:
function (...$vals) use ($main) {
return array_combine($main, $vals);
}
Though I would first point out that this is a rather peculiar dataset to end up with, and you should maybe see if there's something you can do before this to get your data in better shape so you don't need to bend over backwards like this in the first place.
The solution using array_map and array_combine functions:
$result = array_map(function($v) use($main){
return array_combine($main, $v);
}, array_map(null, $fname, $age));
print_r($result);
The same can be achieved with regular foreach loop + array_combine function:
$result = [];
foreach ($fname as $k => $v) {
$result[] = array_combine($main, [$v, $age[$k]]);
}
The output:
Array
(
[0] => Array
(
[Name] => Peter
[Age] => 35
)
[1] => Array
(
[Name] => Ben
[Age] => 37
)
[2] => Array
(
[Name] => Joe
[Age] => 43
)
)
this is what you want :
$newArray = [];
$main = array("Name","Age");
$fname =array("Peter","Ben","Joe");
$age = array("35","37","43");
$newArray = array_combine($fname, $age);
$array = [];
foreach($newArray as $key => $value) {
$array[] = [
$main[0] => $key,
$main[1] => $value
];
}
var_dump($array);

How to filter out blank values from an array in PHP & Reindex the array

I am printing out the values using print_r($_POST["prod_sizes"]);
print_r($_POST["prod_sizes"]);
So i get output like this => dsf,,thisnajndk,faklsf,klam,flkamlkd,mklmd,l,,adad
After that i use this code:
$sizes = strip_tags(preg_replace('/[^a-z0-9,]/i', '', $_POST["prod_sizes"]));
$var = explode(',', $sizes);
print_r($var);
I get output like
Array
(
[0] => dsf
[1] =>
[2] => thisnajndk
[3] => faklsf
[4] => klam
[5] => flkamlkd
[6] => mklmd
[7] => l
[8] =>
[9] => adad
)
As from the above output we can see that there are some blank values in an array. How to remove those blank values?
PHP's built in array_filter() will do this for you:
$sizes = array_filter($sizes);
Keep in mind that any values are equate to false will also be filtered out. So if zero and null is a valid value you will need to write your own callback to filter by.
If you also want to re-index the keys just use array_values() on the result:
$sizes = array_values(array_filter($sizes));
Replace your code from this line => $var = explode(',', $sizes); & add this:
$var = array_filter(explode(',', $sizes));
$reindexed = array();
foreach ($var as $row)
{
if ($row !== null)
$reindexed[] = $row;
}
print_r($reindexed);
exit();
Let's See The Explaination of the code now
1.) This is 1st reference link from where i took the idea to filer but ass you prnt the array you will see that the array indexes are jumbled => Remove empty array elements
$var = array_filter(explode(',', $sizes));
$reindexed = array();
so we create a new variables reindexed as an array to store the reindexed array value
2.) To remove the jumbled array index and reindex the array i took refernce from this link => How to remove null values from an array?
$reindexed = array();
foreach ($var as $row)
{
if ($row !== null)
$reindexed[] = $row;
}
print_r($reindexed);
Here is the best way:
# Array
$array = array('tomato', '', 'apple', 'melon', 'cherry', '', '', 'banana');
that returns
Array
(
[0] => tomato
[1] =>
[2] => apple
[3] => melon
[4] => cherry
[5] =>
[6] =>
[7] => banana
)
by doing this
$array = array_values(array_filter($array));
you get this
Array
(
[0] => tomato
[1] => apple
[2] => melon
[3] => cherry
[4] => banana
)
Explanation
array_values() : Returns the values of the input array and indexes numerically.
array_filter() : Filters the elements of an array with a user-defined function (UDF If none is provided, all entries in the input table valued FALSE will be deleted.)

Convert string with two delimiters into flat associative array [duplicate]

This question already has answers here:
Explode a string to associative array without using loops? [duplicate]
(10 answers)
Closed 7 months ago.
I'm really have no idea about regex...
So I got stuck... Can anyone give me a solution with explanation of regex itself?
Here is my code:
$str = "id:521082299088|name:JOHNSON GREIG DENOIA|mounth:JAN17|amount:170027|admin:2500|billqty:1|metre:R1/900|usage:00010261-00010550|reffno:0BKP21851AF3EC2E0D4F56997EA19DFA|charge:170377|balace:1935";
$pregsplit = preg_split("/[\s|]+/",$string2);
Output:
Array
(
[0] => id:521082299088
[1] => name:JOHNSON
[2] => GREIG
[3] => DENOIA
[4] => mounth:JAN17
[5] => amount:170027
[6] => admin:2500
[7] => billqty:1
[8] => metre:R1/900
[9] => usage:00010261-00010550
[10] => reffno:0BKP21851AF3EC2E0D4F56997EA19DFA
[11] => charge:170377
[12] => balance:1935
)
I want output like this:
Array
(
"id" => 521082299088
"name" => "JOHNSON GREIG DENOIA"
"mount" => "JAN17"
"amount" => 170027
"admin" => 2500
"billqty" => 1
"metre" => "R1/900"
"usage" => "00010261-00010550"
"reffno" => "0BKP21851AF3EC2E0D4F56997EA19DFA"
"charge" => 170377
"balance" => 1935
)
1) The solution using preg_match_all function with specific regex pattern:
$str = "id:521082299088|name:JOHNSON GREIG DENOIA|mounth:JAN17|amount:170027|admin:2500|billqty:1|metre:R1/900|usage:00010261-00010550|reffno:0BKP21851AF3EC2E0D4F56997EA19DFA|charge:170377|balace:1935";
preg_match_all("/(\w+):([^|]+)/", $str, $matches, PREG_SET_ORDER);
$result = [];
foreach ($matches as $items) {
$result[$items[1]] = $items[2];
}
// $items[1] contains a "parameter" name captured by the first capturing group (\w+)
// $items[2] contains a "parameter" value captured by the second capturing group ([^|]+)
print_r($result);
The output:
Array
(
[id] => 521082299088
[name] => JOHNSON GREIG DENOIA
[mounth] => JAN17
[amount] => 170027
[admin] => 2500
[billqty] => 1
[metre] => R1/900
[usage] => 00010261-00010550
[reffno] => 0BKP21851AF3EC2E0D4F56997EA19DFA
[charge] => 170377
[balace] => 1935
)
(\w+) - matches all alphanumeric characters followed by :
([^|]+) - matches all characters excepting | which is delimiter
http://php.net/manual/en/function.preg-match-all.php
2) In addition to the first approach - using array_combine function(to combine all respective values from two capturing groups):
preg_match_all("/(\w+):([^|]+)/", $str, $matches);
$result = array_combine($matches[1], $matches[2]);
// will give the same result
3) The third alternative approach would be using explode() function:
$result = [];
foreach (explode("|", $str) as $items) {
$pair = explode(":", $items);
$result[$pair[0]] = $pair[1];
}
If you are unable to write regular expression.Here is a simple solution using explode() method.The explode() function breaks a string into an array.
<?php
$str = "id:521082299088|name:JOHNSON GREIG DENOIA|mounth:JAN17|amount:170027|admin:2500|billqty:1|metre:R1/900|usage:00010261-00010550|reffno:0BKP21851AF3EC2E0D4F56997EA19DFA|charge:170377|balace:1935";
$array = explode('|',$str);
foreach($array as $key=>$value){
$data = explode(':',$value);
$final[$data[0]] = $data[1];
}
print_r($final);
?>
Output:
Array
(
[id] => 521082299088
[name] => JOHNSON GREIG DENOIA
[mounth] => JAN17
[amount] => 170027
[admin] => 2500
[billqty] => 1
[metre] => R1/900
[usage] => 00010261-00010550
[reffno] => 0BKP21851AF3EC2E0D4F56997EA19DFA
[charge] => 170377
[balace] => 1935
)
To learn more about explode() read docs http://php.net/manual/en/function.explode.php
A funny way (only if your string doesn't contain = or &): translate pipes to ampersands and colons to equal signs, then parse it as an URL query with parse_str:
$str = "id:521082299088|name:JOHNSON GREIG DENOIA|mounth:JAN17|amount:170027|admin:2500|billqty:1|metre:R1/900|usage:00010261-00010550|reffno:0BKP21851AF3EC2E0D4F56997EA19DFA|charge:170377|balace:1935";
parse_str(strtr($str, ':|', '=&'), $result);
print_r($result);
demo
This approach would be an alternative.
You can separate string and create an array from it using PHP's explode() function. Then you can separate the 'key:value' structure using strpos() and substr() functions.
// input string
$str = "id:521082299088|name:JOHNSON GREIG DENOIA|mounth:JAN17|amount:170027|admin:2500|billqty:1|metre:R1/900|usage:00010261-00010550|reffno:0BKP21851AF3EC2E0D4F56997EA19DFA|charge:170377|balace:1935";
// make an array out of the string, split elements on each pipe character ('|')
$arr = explode('|', $str);
// create an output array to keep the results
$output = [];
// process the array
foreach ($arr as $item) {
// get delimiter
$separatorPos = strpos($item, ':');
// take the key part (The part before the ':')
$key = substr($item, 0, $separatorPos);
// take the value part (The part after the ':')
$value = substr($item, $separatorPos);
// push it into the output array
$output[$key] = $value;
}
// dump the output array
var_export($output);
Dump of the output array would be like follwing;
[
'id' => ':521082299088',
'name' => ':JOHNSON GREIG DENOIA',
'mounth' => ':JAN17',
'amount' => ':170027',
'admin' => ':2500',
'billqty' => ':1',
'metre' => ':R1/900',
'usage' => ':00010261-00010550',
'reffno' => ':0BKP21851AF3EC2E0D4F56997EA19DFA',
'charge' => ':170377',
'balace' => ':1935',
]

Is this possible with preg_match?

i have strings that looks similar like this:
"size:34,35,36,36,37|color:blue,red,white"
is it possible to match all the colors in a preg_match(_all)?
so that i will get "blue", "red" and "white" in the output array?
the colors can be whatever, so i cant go (blue|red|white)
Explode on |
Explode on :
Explode on ,
???
Profit!
Code
IMHO using regular expressions like what's been suggested in the other answers is a much "uglier" solution than something simple like so:
$input = 'size:34,35,36,36,37|color:blue,red,white|undercoating:yes,no,maybe,42';
function get_option($name, $string) {
$raw_opts = explode('|', $string);
$pattern = sprintf('/^%s:/', $name);
foreach( $raw_opts as $opt_str ) {
if( preg_match($pattern, $opt_str) ) {
$temp = explode(':', $opt_str);
return $opts = explode(',', $temp[1]);
}
}
return false; //no match
}
function get_all_options($string) {
$options = array();
$raw_opts = explode('|', $string);
foreach( $raw_opts as $opt_str ) {
$temp = explode(':', $opt_str);
$options[$temp[0]] = explode(',', $temp[1]);
}
return $options;
}
print_r(get_option('undercoating', $input));
print_r(get_all_options($input));
Output:
Array
(
[0] => yes
[1] => no
[2] => maybe
[3] => 42
)
Array
(
[size] => Array
(
[0] => 34
[1] => 35
[2] => 36
[3] => 36
[4] => 37
)
[color] => Array
(
[0] => blue
[1] => red
[2] => white
)
[undercoating] => Array
(
[0] => yes
[1] => no
[2] => maybe
[3] => 42
)
)
You can achieve it in a round about way with preg_match_all() but I'd recommend explode instead.
preg_match_all('/([a-z]+)(?:,|$)/', "size:34,35,36,36,37|color:blue,red,white", $a);
print_r($a[1]);
I think it's possible with lookbehind:
/(?<=(^|\|)color:([^,|],)*)[^,|](?=\||,|$)/g
(for preg_match_all)
Your explode solution is obviously cleaner :-)

Categories