I have a long multidimensional array with timestamps as keys which contain arrays of values. Something like this but with more timestamps:
array(3) {
[1502609400]=>
array(2) {
["Item1"]=>
array(1) {
["PRICE"]=>
float(100)
}
["Item2"]=>
array(1) {
["PRICE"]=>
float(50)
}
}
[1502611200]=>
array(2) {
["Item1"]=>
array(1) {
["PRICE"]=>
float(200)
}
["Item2"]=>
array(1) {
["PRICE"]=>
float(150)
}
}
[1502613000]=>
array(2) {
["Item1"]=>
array(1) {
["PRICE"]=>
float(500)
}
["Item2"]=>
array(1) {
["PRICE"]=>
float(250)
}
}
How can I remove every every second array of the array without losing the keys as timestamp? So I end up with this:
array(3) {
[1502609400]=>
array(2) {
["Item1"]=>
array(1) {
["PRICE"]=>
float(100)
}
["Item2"]=>
array(1) {
["PRICE"]=>
float(50)
}
}
[1502613000]=>
array(2) {
["Item1"]=>
array(1) {
["PRICE"]=>
float(500)
}
["Item2"]=>
array(1) {
["PRICE"]=>
float(250)
}
}
If I use a for loop and unset every second key I lose all the keys and end up with 0, 1, 2 etc. instead of the timestamp.
In a loop, check for index and unset every second element:
You can use custom $index variable, like this:
$index = 0; // points to first element
foreach ($array as $key => $value) {
if ($index % 2 != 0) { //check for un-even
unset($array[$key]);
}
$index++; // move pointer to next element
}
$i=1 // where the key to remove
$x=0; //loop to determine the key position
foreach ($array as $key=>$value){
if($x==$i){
unset($array[$key]);
}
$x++;
}
In that kind of case, a simple foreach can be more efficient perfwise than a standard function :
foreach ($array as $key => $val) {
if (array_key_exists('Item2', $val)) {
unset($val['Item2']);
}
}
Related
I checked this question and answers:
How to group a multidimensional array by a particular subarray value?
He wanted to group results by 'level'. But how would you do it to group it by 'level' first and then by 'type'?
Its pretty straight forward. Loop through $items array. Get each item's level and type and if they are not set yet, initialize them with an empty array. Then just push the "cust" value into the array.
I have given the code below.
I am assuming "$items" is an array which contains the input.
$g = [];
foreach($items as $k => $v) {
$l = $v["level"];
$t = $v["type"];
$c = $v["cust"];
if(!isset($g[$l])) {
$g[$l] = [];
}
if(!isset($g[$l][$t])) {
$g[$l][$t] = [];
}
$g[$l][$t][] = [
"cust" => $c
];
}
var_dump($g);
The output of this code would be like below:
array(3) {
[1]=>
array(1) {
["standard"]=>
array(2) {
[0]=>
array(1) {
["cust"]=>
string(6) "XT8900"
}
[1]=>
array(1) {
["cust"]=>
string(6) "XT8944"
}
}
}
[3]=>
array(1) {
["premier"]=>
array(2) {
[0]=>
array(1) {
["cust"]=>
string(6) "XT8922"
}
[1]=>
array(1) {
["cust"]=>
string(6) "XT8816"
}
}
}
[7]=>
array(1) {
["standard"]=>
array(1) {
[0]=>
array(1) {
["cust"]=>
string(6) "XT7434"
}
}
}
}
[P.S.]: You can also use sort to solve this problem easily. That's another way of solving this problem.
I have an array that consists of the keys:
$countries = ['EU', 'UK', 'Asia'];
Another array that consists of further elements based on those keys:
$countries_array=['UK'=>['London', 'Birmingham', 'Manchester'], 'EU'=> ['Germany','Netherlands'] , 'Asia'=> ['Pakistan','Bangladesh','China']];
$mid_countries[];
I want to pass through all the elements, check if they are empty or not and then further create another array. I have written a code and it works fine. But it has foreach loops. Is there any way that I could optimize this code?
foreach ($countries as $each_country) {
if (!empty($countries_array["$each_country"][0])) {
foreach ($countries_array["$each_country"] as $value) {
$mid_countries[] = array("wildcard" => array("$each_country" => $value. "*"));
}
}
}
Expected result:
array(8) {
[0]=> array(1) { ["wildcard"]=> array(1) { ["EU"]=> string(8) "Germany*" } } [1]=> array(1) { ["wildcard"]=> array(1) { ["EU"]=> string(12) "Netherlands*"}}
[2]=> array(1) { ["wildcard"]=> array(1) { ["UK"]=> string(7) "London*" } } [3]=> array(1) { ["wildcard"]=> array(1) { ["UK"]=> string(11) "Birmingham*" } } [4]=> array(1) { ["wildcard"]=> array(1) { ["UK"]=> string(11) "Manchester*" } } [5]=> array(1) { ["wildcard"]=> array(1) { ["Asia"]=> string(9) "Pakistan*" } } [6]=> array(1) { ["wildcard"]=> array(1) { ["Asia"]=> string(11) "Bangladesh*"}}
[7]=> array(1) { ["wildcard"]=> array(1) { ["Asia"]=> string(6) "China*" } } }
I think you expected this (Code updated use its working in single loop)
foreach ($countries_array as $key=>$value) {
$tmp=implode('*#'.$key.'#',$value);
$tmp='#'.$key.'#'.$tmp."*";
$tmp=str_replace('#'.$key.'#',"\"}},{\"wildcard\":{\"".$key."\":\"",$tmp);
$result=$result.substr($tmp,3)."\"}}";
}
$result="[".ltrim($result,"\"}},")."]";
$result=json_decode($result,true);
print_r($result);
array(1) {
["farm"]=>
array(2) {
["folder1"]=>
array(2) {
["horse"]=>
array(1) {
["fred.jpg"]=>
string(30) "farm/folder1/horse/fred.jpg"
}
["cat"]=>
array(1) {
["john.jpg"]=>
string(28) "farm/folder1/cat/john.jpg"
}
}
["folder2"]=>
array(1) {
["cat"]=>
array(2) {
["sam.jpg"]=>
string(27) "farm/folder2/cat/sam.jpg"
["cat"]=>
array(1) {
["john.jpg"]=>
string(32) "farm/folder2/cat/cat/john.jpg"
}
}
}
}
}
Is it possible to detect only the most inner array keys?
foreach($array as $key => $value){
if ($key == $most_inner_array) {
echo $key;
}
}
So that in this case the result would be:
fred.jpg
john.jpg
sam.jpg
john.jpg
You can go through your array recursively and print the key if the value is not an array.
In case of just printing a value like in your example, you can do it with just array_walk_recursive() without any condition. Something like:
array_walk_recursive($your_array, function($value, $key) {
echo $key . "\n";
});
I have a PHP Loop that loops through data, i want to be able to echo all of this data alphabetically.
i currently use an array:
$output[]=array();
foreach($WHM_Servers as $whm) {
foreach($server->list_accounts() as $ret) {
$output[]= '<tr class="notfirst">
<td>'.$ret["domain"].'</td>
<td>'.$ret["user"].'</td>
<td>'.CompanyInfoLookup($result["customer"], 'company').'</td>
<td>'.$ret["startdate"].'</td>
<td>'.$ret["starttime"].'</td>
<td>'.$ret["disklimit"].'</td>
<td>'.$ret["diskused"].'</td>
</tr>';
}
}
would i be able to add a key in the array and then echo the array alphabetically from the keys
A few different ways to do this, I chose to write a user defined sort function.
$accounts = array();
$accounts[]['name'] = "Tom";
$accounts[]['name'] = "Frank";
$accounts[]['name'] = "Zed";
$accounts[]['name'] = "Aaron";
function compareNames($a, $b){
return strcmp($a['name'], $b['name']);
}
usort($accounts, "compareNames");
var_dump($accounts);
Output:
array(4) {
[0]=>
array(1) {
["name"]=>
string(5) "Aaron"
}
[1]=>
array(1) {
["name"]=>
string(5) "Frank"
}
[2]=>
array(1) {
["name"]=>
string(3) "Tom"
}
[3]=>
array(1) {
["name"]=>
string(3) "Zed"
}
}
This is a standalone example. To apply it to your example, you need to store the data: $accounts = $server->list_accounts(), sort it: usort($accounts, "compareNames");, and then pass it in to your loop: foreach($accounts as $ret) {
I have a csv file which I am trying to turn into a different structured array. First, I turn it into an array named all_data() constructed like this:
$data = file_get_contents($id . '.csv');
$data_array = explode("\n", $data);
foreach($data_array AS $data){
$all_data[] = explode("\t", $data);
}
results look like this:
array(5) {
[0]=>
array(2) {
[0]=>
string(10) "2012-11-14"
[1]=>
string(2) "10"
}
[1]=>
array(2) {
[0]=>
string(10) "2012-11-14"
[1]=>
string(2) "10"
}
[2]=>
array(2) {
[0]=>
string(10) "2012-11-14"
[1]=>
string(2) "10"
}
[3]=>
array(2) {
[0]=>
string(10) "2012-11-14"
[1]=>
string(2) "10"
}
[4]=>
array(1) {
[0]=>
string(0) ""
}
}
And then I turn it into im_arr() with the following code:
foreach($all_data as $key => $value){
$im_arr[$key][$value[0]] = $value[1];
}
The results:
array(5) {
[0]=>
array(1) {
["2012-11-14"]=>
string(2) "10"
}
[1]=>
array(1) {
["2012-11-14"]=>
string(2) "10"
}
[2]=>
array(1) {
["2012-11-14"]=>
string(2) "10"
}
[3]=>
array(1) {
["2012-11-14"]=>
string(2) "10"
}
[4]=>
array(1) {
[""]=>
NULL
}
}
And then, finally another foreach loop gives me the results I am looking for:
foreach ($im_arr as $val) {
foreach ($val as $key => $val2) {
$im_data[$key]=$val2;
}
}
With the result for im_data() being:
array(2) {
["2012-11-14"]=>
string(2) "10"
[""]=>
NULL
}
Which would be perfect, since the array im_data() is exactly what I would like to get out of all_data(). However, when I am trying to put this code in another part of the program it doesn't work, and I am thinking it might be because of the warnings I receive:
"PHP Notice: Undefined offset: 1 in ... on line 93"
Line 93 corresponds to this line:
$im_arr[$key][$value[0]] = $value[1];
Here is the complete part of the code:
$all_data = array();
$im_arr=array();
$data = file_get_contents($id . '.csv');
$data_array = explode("\n", $data);
foreach($data_array AS $data){
$all_data[] = explode("\t", $data);
}
foreach($all_data as $key => $value){
$im_arr[$key][$value[0]] = $value[1]; //the line for the error
}
$im_data=array();
foreach ($im_arr as $val) {
foreach ($val as $key => $val2) {
$im_data[$key]=$val2;
}
}
var_dump($im_data);
I know there are many many questions posted for this same error, but I couldn't figure out the problem with this particular piece of code.
This is the problem:
[4]=>
array(1) {
[0]=>
string(0) ""
}
Just check that the data is set, and isn't empty before adding them to $im_arr:
foreach ($all_data as $key => $value) {
if (isset($value[0]) && isset($value[1]) && !empty($value[0]) && !empty($value[1])) {
$im_arr[$key][$value[0]] = $value[1];
}
}
For every foreach i would pre-check if the first argument is an array
For instance ;
//Just add line below for every foreach (and add any required else statement if needed)
if(is_array($im_arr))
foreach ($im_arr as $val) {
if(is_array($val))
foreach ($val as $key => $val2) {
$im_data[$key]=$val2;
}
}