This question already has answers here:
Remove all elements from array that do not start with a certain string
(10 answers)
Closed 9 years ago.
I have a large SQL query which returns aggregate data.
My returned array is something like this:
array(37) { // I get 37 arrays returned
[0] => array(10) {
["groupId"] => string(1) "3" // the first param is just an id
["sessionCount84"] => string(1) "0"
["sessionCount1"] => string(1) "1"
} ...
Each sub-array will contains multiple keys with the word 'sessionCount' and a number following that and there could be many of them.
Is there a way to get all the values for keys which contain the words 'sessionCount[someNumber]" ?
I tried the array_keys function in php, but that requires an exact word match, meaning I would need to know the number following 'sessionCount' in the key, so I'd need to get all the keys that contain that word first somehow.
$tmp = array();
foreach ($array as $sub)
foreach ($sub as $k => $v)
if (substr($k, 0, 12) == 'sessionCount')
$tmp[$k] = $v;
Perhaps something like this will help.
$myArray = array(37) { [0]=> // I get 37 arrays returned
array(10) { ["groupId"]=> string(1) "3" // the first param is just an id
["sessionCount84"]=> string(1) "0"
["sessionCount1"]=> string(1) "1" } ...
$sessions = array();
array_map(function($session) use (&$sessions) {
foreach ($session as $key => $value) {
if ($key starts with "sessionCount") // I'm going to leave that up to you
$sessions[$key] = $value;
}
}, $myArray);
without changing the array you can only do this by brute force.. aka. try "sessionCount[0-999]"..
a different approach would be to use strcmp() on the array keys like so:
foreach($array as $key => $value)
if(!strcmp($key,"sessionCount"))
dosomething($key,$value);
or loop through your array once and restructure it to something like this:
array() {
["sessionCount"] => array() {
[84] => "",
[1] => "",
}
}
..after that finding all the keys you require should be a walk in the park. ;)
Related
I'm studying php and I'm trying to figure out how to get the string "Juve_Milan" from this var_dump($_POST) :
array(5) {
["Juve_Milan"] => array(2) {
[0] => string(1)
"5" [1] => string(1)
"1"
}["Inter_Roma"] => array(2) {
[0] => string(1)
"4" [1] => string(1)
"4"
}["Napoli_Lazio"] => array(2) {
[0] => string(1)
"2" [1] => string(1)
"5"
}["name"] => string(0)
"" ["submit"] => string(5)
"Invia"
}
I could get all of them with:
foreach ($_POST as $param_name => $param_val) {
echo "<tr><td>".$param_name."</td><td>".$param_val[0]."-".$param_val[1]."</td></tr>";
}
But i want to get them exactly one by one, for example, if i want to get the string "Juve_Milan" or "inter_Roma" how can i do?
Without looping, how can i get the string value: "Juve_milan" or "Inter_Roma"? Becouse with the loop i can access them this way : $_POST as $param_name => $param_val
But i want to get them without loop, my first attempt was something like $_POST[0][0] but its wrong...
There are numbers of php array functions you can use.
You can use
array shift
to remove an element from an array and display it .e.g
$club = ['juve_millan', 'inter_roma', 'napoli_lazio'];
$juve = array_shift($club);
echo $juve;// 'juve_millan'
but note that the array is shortened by one element i.e. 'juve_millan' is no more in the array and also note that using
array_shift
over larger array is fairly slow
Array Slice function
PHP
array_slice()
function is used to extract a slice of an array e.g
$club = ['juve_millan', 'inter_roma', 'napoli_lazio'];
if I want to display
inter_roma
or assigned it to a variable, then I can do this
$roma = array_slice($club, 1, 1);// The first parameter is the array to slice, the second parameter is where to begin(which is one since most programming language array index start from 0 meaning juve_millan is zero, while inter_roma is 1, napoli_lazio is 2) and the length is 1 since i want to return a single element.
I hope you understand
You could iterate over keys of the main array like this:
foreach($_POST as $param_name => $param_val) {
echo "<tr><td>".$param_name."</td></tr>";
}
This will return each Juve_Milan, Inter_Roma etc. one by one. Although it's part of the code you already have, I believe this will return values you want only.
I have a multidimensional array that I am trying to search for a specific value (url) and then retrieve an another value in the same row (value). I also need to divert to an else if it is not found.
array(2) {
[0]=> array(2) {
["url"]=> string(7) "fareham"
["value"]=> string(7) "Fareham"
}
[1]=> array(2) {
["url"]=> string(11) "southampton"
["value"]=> string(11) "Southampton"
}
}
I have been experimenting with array_key_exists() and isset() to check it's set and just coming up null!
For example, if I search for fareham, I want to return Fareham. If I search for nottingham, I expect null.
How can I isolate the qualifying value?
Use array_column() to index the data by the url columns and then use isset() to check if the value is there...
$data = array_column($data, "value", "url");
$search = 'southampton';
$value = isset($data[$search])?$data[$search]:"not found";
echo $value;
or for PHP 7+, you can use the null coalescing operator (??)
$value = $data[$search]??"not found";
Here is the minimal way to do it (no checks)
$a = array (
0 =>
array (
"url" => 'fareham',
"value" => 'Fareham'
),
1 =>
array (
"url" => 'southampton',
"value" => 'Southampton'
)
);
$u = 'fareham';
$i = $a[false===($f=array_search($u,array_column($a,'url')))?-1:$f]['value'];
print_r($i);
Output
Fareham
Sandbox
How it works
First we create an array we can search by using array_column on the column we want to search in this case url. It looks like this [0=>'fareham', 1=>'southampton']
Then we use the normal array_search which returns an index, if you notice above the indexes are correlated to the original array. Which means we can put that in as the top level key, then it's a simple matter of adding the key we want.
Because array_search can return a boolean(false) which PHP sees as 0 or the first index I put a little hack in for that. But a better way is to check it like this:
$a = array (
0 =>
array (
"url" => 'fareham',
"value" => 'Fareham',
"extra" => 'Foo'
),
1 =>
array (
"url" => 'southampton',
"value" => 'Southampton',
"extra" => 'Bar'
)
);
function serchMultiDimensionalValue($needle, $haystack, $fields='value'){
if(false === ($f=array_search($needle,array_column($haystack,'url')))) return false; //or return [];
if(!is_array($fields)) $fields = [$fields];
return array_intersect_key($haystack[$f], array_flip($fields));
}
var_dump(serchMultiDimensionalValue('foo',$a));
var_dump(serchMultiDimensionalValue('fareham',$a));
var_dump(serchMultiDimensionalValue('fareham',$a, 'extra'));
var_dump(serchMultiDimensionalValue('fareham',$a, ['extra','url']));
Ouput
bool(false)
array(1) {
["value"]=>
string(7) "Fareham"
}
array(1) {
["extra"]=>
string(3) "Foo"
}
array(2) {
["url"]=>
string(7) "fareham"
["extra"]=>
string(3) "Foo"
}
Sandbox
I added a bit more "functionality" to it, hope you don't mind.
While it might be alluring to seek out a one-liner like:
array_column($array, $returnColumn, $haystackColumn)[$needle] ?? null
Be aware that array_column() will be unconditionally doubling the memory usage (because it is generating a new array with the same length as the original) for the sake of assigning new first level keys to search by.
Metaphorically speaking, it is like building a new registry of residences in a neighborhood including every homeowner's name and their address. Yes, you can find out who lives at a given home without knocking on the front door, but you had to knock on every door to collect every home's details before enjoying this convenience. Why not just knock on the door of each original house and ask if they are who you are looking for? It is much easier, and you will be able to "quit" early as soon as you find the homeowner that you are looking for.
For best efficiency and for least memory usage, I recommend the below classic loop with conditional break. It is built with dynamic search and return variables for general usage, but you can use hardcoded values if you like.
Code: (Demo)
$array = [
["url" => 'fareham', "value" => 'Fareham'],
["url" => 'southampton', "value" => 'Southampton']
];
$needle = 'fareham';
$haystackColumn = 'url';
$returnColumn = 'value';
$value = null;
foreach ($array as $row) {
if ($row[$haystackColumn] === $needle) {
$value = $row[$returnColumn];
break;
}
}
var_export($value); // 'Fareham'
This question already has answers here:
Transposing multidimensional arrays in PHP
(12 answers)
Closed 1 year ago.
I have the following associative array of column data:
$where = array(
'id'=>array(
12,
13,
14
),
'date'=>array(
'1999-06-12',
'2000-03-21',
'2006-09-31'
)
);
I need to transpose / rotate the structure to be an array of rows (with merged column data assigned to their respective row). I don't need the column names in the result.
Expected output:
$comb = array(
array(12, '1999-06-12'),
array(13, '2000-03-21'),
array(14, '2006-09-31')
);
As Kris Roofe stated in his deleted answer, array_column is indeed a more elegant way. Just be sure to put it into some kind of a foreach loop, similar to what Sahil Gulati showed you. For example, like this:
$result = array();
foreach($where['id'] as $k => $v)
{
$result[] = array_column($where, $k);
}
The var_dump output of $result is exactly what you're looking for
array(3) {
[0]=>
array(2) {
[0]=>
int(12)
[1]=>
string(10) "1999-06-12"
}
[1]=>
array(2) {
[0]=>
int(13)
[1]=>
string(10) "2000-03-21"
}
[2]=>
array(2) {
[0]=>
int(14)
[1]=>
string(10) "2006-09-31"
}
}
Solution 1: Hope this simple foreach to get the desired result
Try this code snippet here
<?php
ini_set('display_errors', 1);
$where = array('id'=>array(12,13,14),'date'=>array('1999-06-12','2000-03-21','2006-09-31'));
$result=array();
foreach($where["id"] as $key => $value)
{
$result[]=array($value,$where["date"][$key]);
}
Solution 2: Here we are using array_walk to achieve the same result
Try this code snippet here
<?php
ini_set('display_errors', 1);
$result=array();
$where = array('id'=>array(12,13,14),'date'=>array('1999-06-12','2000-03-21','2006-09-31'));
array_walk($where["id"], function($value,$key) use(&$result,&$where){
$result[]=array($value,$where["date"][$key]);
});
print_r($result);
Solution 3: Here we are using array_shift on $where["date"].
Try this code snippet here
<?php
ini_set('display_errors', 1);
$result=array();
$where = array('id'=>array(12,13,14),'date'=>array('1999-06-12','2000-03-21','2006-09-31'));
foreach($where["id"] as $value)
{
$result[]=array($value, array_shift($where["date"]));
}
print_r($result);
I've completely re-written my answer because it was unnecessarily bloating this page. Truth is, there is a very clean and native way to handle this specific task of "transposing". Using null as the function argument and passing in the two known rows from the input array is all that is required.
Code: (Demo)
$where = [
'id' => [12, 13, 14],
'date' => ['1999-06-12', '2000-03-21', '2006-09-31']
];
var_export(
array_map(null, $where['id'], $where['date'])
);
Output:
array (
0 =>
array (
0 => 12,
1 => '1999-06-12',
),
1 =>
array (
0 => 13,
1 => '2000-03-21',
),
2 =>
array (
0 => 14,
1 => '2006-09-31',
),
)
For anyone that truly needs a dynamic solution (because the number of rows may fluxuate/change and you don't want to keep maintaining the processing code), then I recommend that you check the version history of my answer.
I have a relatively large array of elements which I want to search for a string and replace any matches. I'm currently trying to do this using preg_replace and regular expressions:
preg_replace("/\d?\dIPT\.\w/", "IPT", $array);
I want to get all values which match either 00IPT.A or 0IPT.A (with 0 representing any numerical character and A representing any letter) and replace them with IPT. However, I'm getting array to string conversion notices. Is there any way to get preg_replace to accept an array data source? If not, is there any other way I could achieve this?
The documentation says that preg_replace should be able to accept array sources — this is the reason I'm asking.
The string or an array with strings to search and replace.
If subject is an array, then the search and replace is performed on every entry of subject, and the return value is an array as well.
The array is multidimensional if that helps (has multiple arrays under one main array).
preg_replace doesn't modify in place. To permanently modify $array, you simply need to assign the result of preg_replace to it:
$array = preg_replace("/\d{1,2}IPT\.\w/", "IPT", $array);
works for me.
$array = array('00IPT.A', '0IPT.A');
$array = preg_replace("/\d{1,2}IPT\.\w/", "IPT", $array);
var_dump($array);
// output: array(2) { [0]=> string(3) "IPT" [1]=> string(3) "IPT" }
Note: the \d{1,2} means one or two digits.
If you want to do this to a two-dimensional array, you need to loop through the first dimension:
$array = array( array('00IPT.A', 'notmatch'), array('neither', '0IPT.A') );
foreach ($array as &$row) {
$row = preg_replace("/\d{1,2}IPT\.\w/", "IPT", $row);
}
var_dump($array);
output:
array(2) {
[0]=> array(2) {
[0]=> string(3) "IPT"
[1]=> string(8) "notmatch"
}
[1]=> &array(2) {
[0]=> string(7) "neither"
[1]=> string(3) "IPT"
}
}
Note that you have to loop through each row by reference (&$row) otherwise the original array will not be modified.
Your value does not sit in the array as a simple element but as a subset right? Like so?
array (
array ('id' => 45, 'name' => 'peter', 'whatyouarelookingfor' => '5F'),
array ('id' => 87, 'name' => 'susan', 'whatyouarelookingfor' => '8C'),
array ('id' => 92, 'name' => 'frank', 'whatyouarelookingfor' => '9R')
)
if so:
<?php
foreach ($array as $key => $value) {
$array[$key]['whatyouarelookingfor'] =
preg_replace("/\d?\dIPT\.\w/", "IPT", $value['whatyouarelookingfor']);
}
Or if more elements have this, just go broader:
<?php
foreach ($array as $key => $value) {
$array[$key] =
preg_replace("/\d?\dIPT\.\w/", "IPT", $value);
}
your $array contains some further arrays. preg_replace works fine with arrays of strings, but not with arrays of arrays [of arrays...] of strings.
here is the code im having trouble with
$key = array(
"0" => "sss",
"1" => "wst",
"2" => "sfv",
"3" => "lac",
"4" => "sgv",
"5" => "lgb",
"6" => "ant"
);
$urls = array(
"0" => "http://www.sarmenhb.com/index.php?key=",
"1" => "http://www.navidoor.com/index.php?key=",
"2" => "http://www.worldexchange.com/index.php?key=",
"3" => "http://www.iaddesign.com/index.php?key=",
"4" => "http://www.iadesignandstudio.com/index.php?key=",
"5" => "http://www.redlineautoleasing.com/index.php?key="
);
for($a=0;$a <= count($urls);$a++) {
foreach($key as $keys) {
print $urls[$a].$keys[$a]."<br/>";
}
}
print "<br/><br/>";
i am trying to make the output look like this:
http://www.sarmenhb.com/index.php?key=sss
http://www.navidoor.com/index.php?key=sss
http://www.worldexchange.com/index.php?key=sss
http://www.iaddesign.com/index.php?key=sss
http://www.iadesignandstudio.com/index.php?key=sss
http://www.redlineautoleasing.com/index.php?key=sss
http://www.sarmenhb.com/index.php?key=wst
http://www.navidoor.com/index.php?key=wst
http://www.worldexchange.com/index.php?key=wst
http://www.iaddesign.com/index.php?key=wst
http://www.iadesignandstudio.com/index.php?key=wst
http://www.redlineautoleasing.com/index.php?key=wst
etc including all key values included as a value the the param key
ive removed the origional urls to prevent url hacking but how can i print an output like that?
the output i keep getting is key=s or key=w the whole key value isnt displaying. along with an error of Notice: Uninitialized string offset: 3 in D:\wamp\www\MVC\t.php on line 32
please help
thank alot!
foreach($key as $string)
{
foreach($urls as $address)
{
echo $address . $string . "<br/>";
}
}
I would simply do two foreach statements:
foreach($urls as $url) {
foreach($keys as $key) {
print $url.$key."\n";
}
}
I also recommend you to pluralize the name of your arrays for simple readability, check the output here.
That's because you're printing $keys[$a]. $keys is a string from your array, and $a would just get a single character. You can select characters in strings the same way you select variable from array.
If you remove the square brackets it should work.
print $urls[$a].$keys."<br/>";
Remove the foreach loop and change $keys[$a] to $key[$a].