This question already has answers here:
How can I sort arrays and data in PHP?
(14 answers)
Closed 7 years ago.
I have been tried couple of times before asking here, i've also seen this question
which is similar to mine but unfortunatly it doesnt work (or i can get it working as well).
I have an array like this:
Array (
[user_1] => Array
(
[0] => Array
(
[category] => string_var
[time] => unix_timestamp
),
[1] => Array
(
[category] => string_var
[time] => unix_timestamp
),
[2] => Array
(
[category] => string_var
[time] => unix_timestamp
)
),
[user_2] => Array
(
[0] => Array
(
[category] => string_var
[time] => unix_timestamp
),
[1] => Array
(
[category] => string_var
[time] => unix_timestamp
),
[2] => Array
(
[category] => string_var
[time] => unix_timestamp
)
)
)
And for each user i have to sort the 2nd-level array by timestamp.
Hence, i've tried:
foreach ($array as $user => $user_data) {
timestamps = array();
foreach($user_data as $key => $actual_data) {
$timestamps[$key] = $actual_data['time'];
}
array_multisort($timestamps, SORT_ASC, $user_data);
}
unset($timestamps);
print_r($array); // the original array should now be sorted by timestamp
Well, no sorting happens, the final array is exactly = the original one.
NOTES :
the key ['time'] into the 2nd-level array comes from a MYSQL column
and it's stored as BIGINT. var_dump gives me: int(1432587949), so it shouldnt be a variable type issue
i have also tried usort, with the same result: no sorting.
Where am i wrong? thanks
You want to do something like this:
array_walk($array, function(&$arr) {usort($arr, function($a,$b){return ($a["time"] < $b["time"]) ? -1 : ($a["time"] > $b["time"] ? 1 : 0);});});
But since you said that the data come from a database then I suggest you sort them there because it's likely to be faster than sorting it in php.
Related
This question already has answers here:
Two arrays in foreach loop
(24 answers)
Closed 2 years ago.
I would like to collate data from multiple different data sources into one numeric array using foreach loops, however I am having some trouble building my array in the expected format. I would like to keep the key numeric.
For example, if I had two data sources: $fruit_data and $flavor_data and my code was:
foreach($fruit_data as $fruit){
$fruits[]['name'] = $fruit['name'];
}
foreach($flavor_data as $flavor){
$fruits[]['flavor'] = $flavor['taste'];
}
The data is added to the array with separate numeric keys, like this:
Array
(
[0] => Array
(
[name] => Example Name 1
)
[1] => Array
(
[flavor] => Example Flavor 1
)
[2] => Array
(
[name] => Example Name 2
)
[3] => Array
(
[flavor] => Example Flavor 2
)
)
However, my desired output is to display the data under the same numeric key, like this:
Array
(
[0] => Array
(
[name] => Example Name 1
[flavor] => Example Flavor 1
)
[1] => Array
(
[name] => Example Name 2
[flavor] => Example Flavor 2
)
)
Could somebody please explain where I am going wrong, and if possible, link me to a resource that explains how to overcome this issue? It may be that I have a fundamental misunderstanding of multidimensional arrays, but I cannot seem to find any references to this issue.
Any help is much appreciated.
foreach($fruit_data as $index => $fruit){
$fruits[] = [
'name' => $fruit['name'],
'flavor' => $flavor_data[$index]['taste']
];
}
Same as
foreach($fruit_data as $index => $fruit){
$fruits[] = [
'name' => $fruit_data[$index]['taste'],
'flavor' => $flavor_data[$index]['taste']
];
}
This question already has answers here:
Is there a function to extract a 'column' from an array in PHP?
(15 answers)
Closed 6 months ago.
I'm wondering what the most efficient way to reduce this array down by a level, ideally without loops in PHP. It's a result from mysqli_fetch_all().
Array
(
[0] => Array
(
[ID] => 648546
)
[1] => Array
(
[ID] => 648552
)
[2] => Array
(
[ID] => 650046
)
[3] => Array
(
[ID] => 652732
)
[4] => Array
(
[ID] => 652738
)
[5] => Array
(
[ID] => 652756
)
)
The result I would like is
array(648546,648552,650046,652732,...)
The simple query example it comes from is something as easy as:
SELECT mytable.ID FROM mytable WHERE status =1
This should do it for PHP 5.5+
$result = array_column($array, 'ID');
You can use array_map():
$new_array = array_map(function($v){return $v['ID'];}, $old_array);
You might try this:
SELECT GROUP_CONCAT(mytable.ID)
FROM mytable
WHERE status = 1
GROUP BY status
It should return 1 row with the ID as a comma separated list.
I have the follow array:
$arrIni["ENV"]="US";
$arrIni["sap_db_server"] = "192.xxx.x.xx";
$arrIni["local_db_server"] = "localhost";
$arrIni["local_db_username"] = "root";
//Default settings
$arrIni["arrEnvSettings"]["UserTypeID"]=4;
$arrIni["arrEnvSettings"]["LocalizationID"]=1;
$arrIni["arrEnvSettings"]["LangLabels"] = array();
$arrIni["arrEnvSettings"]["pages"]["st1"]="st1.php";
$arrIni["arrEnvSettings"]["pages"]["st2"]="st2.php";
$arrIni["arrEnvSettings"]["pages"]["st3"]="st3.php";
And I want to merge with this one:
$setParam["arrEnvSettings"]["pages"]["st3"]="st3_V2.php";
This is what I am doing:
echo "<pre>";
print_r(array_merge($arrIni,$setParam));
echo "</pre>";
And this is what I am getting:
Array
(
[ENV] => US
[sap_db_server] => 192.xxx.x.xx
[local_db_server] => localhost
[local_db_username] => root
[arrEnvSettings] => Array
(
[pages] => Array
(
[st3] => st3_V2.php
)
)
)
In the php doc about merge, this is the comment " ...If the input arrays have the same string keys, then the later value for that key will overwrite the previous one. ..."
So in this way, I suppose to get this output instead of the last one:
Array
(
[ENV] => US
[sap_db_server] => 192.xxx.x.xx
[local_db_server] => localhost
[local_db_username] => root
[arrEnvSettings] => Array
(
[UserTypeID] => 4
[LocalizationID] => 1
[LangLabels] => Array
(
)
[pages] => Array
(
[st1] => st1.php
[st2] => st2.php
[st3] => st3_V2.php
)
)
)
I do not understand why $setParam["arrEnvSettings"]["pages"]["st3"] is overriding the entire $arrIni["arrEnvSettings"].
Note:
If I use array_merge_recursive($arrIni,$setParam)) I will have the follow result but it is not what I want.
Array
(
[ENV] => US
[sap_db_server] => 192.xxx.x.xx
[local_db_server] => localhost
[local_db_username] => root
[arrEnvSettings] => Array
(
[UserTypeID] => 4
[LocalizationID] => 1
[LangLabels] => Array
(
)
[pages] => Array
(
[st1] => st1.php
[st2] => st2.php
[st3] => Array
(
[0] => st3.php
[1] => st3_V2.php
)
)
)
)
Is there a way to do this without iterate over the array? Only using merging? What am I doing wrong?
This should do the trick:
array_replace_recursive($arrIni,$setParam);
If you want to merge a given value, use this:
$arrIni["arrEnvSettings"]["pages"]["st3"] = $setParam["arrEnvSettings"]["pages"]["st3"];
But the way you're doing it is merging two arrays, not simply setting the value within an array. There's a gigantic difference between those two methods.
Otherwise, yes you will need to iteratively merge the arrays.
what you need is array_replace_recursive
print_r(array_replace_recursive($arrIni,$setParam));
didnt see the submitted answer..Felippe Duarte has given it already.....
I have an array which has a timestamp consistently on [3] ( an example of the array data below)
I would like the array to be sorted using the timestamp. I've seen a few stackoverflow posts that apparently do this using two methods, array_multisort() and usort() but I've been unable to replicate either.
Here is what I've tried based on my own code:
Attempt 1 - I pass the array to usort, then attempt to take it apart with the foreach. Applying this method definitely changes the order of the results, but the dates seems to be no specific order (ascending, descending).
function sortArray($a1, $a2){
if ($a1[3] == $a2[3]) return 0;
return ($a1[3] > $a2[3]) ? -1 : 1;
}
usort($the_array, "sortArray");
foreach($the_array as $sh) {
$uid = $sh['uid'];
$username = $sh['username'];
$datetime = $sh['datetime'];
$type = $sh['type'];
echo "<p> $uid , $username, $datetime, $type </p>";
}
Attempt 2 - tried using array_multisor() which again gives me results in a different order but I don't understand what it is sorting by exactly.
foreach ($the_array as $key => $node) {
$timestamps[$key] = $node[3];
}
array_multisort($timestamps, SORT_ASC, $the_array);
//process the array with a foreach to show results
My theory here is that it isn't properly processing the unix timestamp and I'm not sure what I can do about that. Is it smart to take out all the characters of the timestamp so it is a simple line of numbers ( 2014-01-02 03:02:12 becomes 20140102030212 )? Or is there another way to process it with the timestamp in it's current form?
Here is an example of the data in the array:
Array
(
[0] => Array
(
[uid] => 20013
[0] => 20013
[username] => myhipswontlie
[1] => myhipswontlie
[rating] => 4.00
[2] => 4.00
[datetime] => 2014-01-27 23:40:56
[3] => 2014-01-27 23:40:56
[type] => rated
[4] => rated
)
[1] => Array
(
[uid] => 20025
[0] => 20025
[username] => brasilchika
[1] => brasilchika
[rating] => 4.00
[2] => 4.00
[datetime] => 2014-01-02 03:02:12
[3] => 2014-01-02 03:02:12
[type] => rated
[4] => rated
)
[2] => Array
(
[uid] => 10002
[0] => 10002
[username] => crtten
[1] => crtten
[datetime] => 2014-01-25 01:33:34
[2] => 2014-01-25 01:33:34
[type] => visits
[3] => visits
)
)
Your issue is your numeric keys don't seem to match up in your arrays. Sometimes the datetime is found in the 3rd key, sometime it is found in the second key (which is odd considering they look like they come from mysql_fetch_array() which will make uniform arrays).
To solve this you should use the associative array key instead:
function sortArray($a1, $a2){
if ($a1['datetime'] == $a2['datetime']) return 0;
return ($a1['datetime'] > $a2['datetime']) ? -1 : 1;
}
usort($the_array, "sortArray");
This question already has answers here:
mysql_fetch_array returns duplicate data
(7 answers)
Closed 9 years ago.
Maybe I have long since gotten to used to using ORM methods to pull data from a DB but I am now working up a simple little project for a buddy of mine who doesn't need all the extra guff of MVC's, ORM's and so on.. With that below is an example of the query I am putting together in a class I am building up in PHP.
$this->sqlstart();
$sql = "select label, setting from ".$this->_settings." where id <= 4";
$query = mysql_query($sql);
$result = array();
while($row = mysql_fetch_array($query))
{
$result[] = $row;
}
return $result;
The output from return $result is:
Array
(
[0] => Array
(
[0] => Week 1 Pay
[label] => Week 1 Pay
[1] => 2995
[setting] => 2995
)
[1] => Array
(
[0] => Week 2 Pay
[label] => Week 2 Pay
[1] => 2995
[setting] => 2995
)
[2] => Array
(
[0] => Week 1 Dates
[label] => Week 1 Dates
[1] => 1-15
[setting] => 1-15
)
[3] => Array
(
[0] => Week 2 Dates
[label] => Week 2 Dates
[1] => 16-31
[setting] => 16-31
)
)
And it should be
Array
(
[0] => Array
(
[label] => Week 1 Pay
[setting] => 2995
)
[1] => Array
(
[label] => Week 2 Pay
[setting] => 2995
)
[2] => Array
(
[label] => Week 1 Dates
[setting] => 1-15
)
[3] => Array
(
[label] => Week 2 Dates
[setting] => 16-31
)
)
can anyone point out to me where the additional data in the sets is coming from?
You should use mysql_fetch_assoc to get the result properly. It will provide you an associative array instead of a normal one.
From http://php.net/manual/en/function.mysql-fetch-array.php
array mysql_fetch_array ( resource $result [, int $result_type = MYSQL_BOTH ] )
Either pass MYSQL_ASSOC as the second param to just get an associative array back, or just call mysql_fetch_assoc().
You should be able to pass in a second argument which will only output the associative column names:
while($row = mysql_fetch_array($query, MYSQL_ASSOC))
mysql_fetch_array returns two ways to access values: field name and index number. You might change mysql_fetch_array to mysql_fetch_assocor change the code to:
while($row = mysql_fetch_array($query)){
$result[] = array('label' => $row['label'], 'setting' => $row['setting'];
}