Sorting an array with similar values - php

I have an array of arrays that contains a date string.
I'd like to sort these arrays by this date.
What seems to be the monkeywrench in this is that some of the arrays share the same value for the date field as well as similar values for tid and/or thing and/or other_thing.
Array (
[0] => Array (
[tid] => 44
[date] => 1442905200
[thing] => 2J5265B
[other_thing] => Scoop
)
[1] => Array (
[tid] => 47
[date] => 1442905200
[thing] => 2J5265B
[other_thing] => Scoop
)
[2] => Array (
[tid] => 48
[date] => 1430031600
[thing] => 2E5116A
[other_thing] => shower
)
[3] => Array (
[tid] => 46
[date] => 1430031600
[thing] => 2E5116A
[other_thing] => shower
)
[4] => Array (
[tid] => 80
[date] => 1464246000
[thing] => 7J6147A
[other_thing] => shower
)
[5] => Array (
[tid] => 47
[date] => 1442905200
[thing] => 2J5265B
[other_thing] => TTT
)
[6] => Array (
[tid] => 44
[date] => 1442905200
[thing] => 2J5265B
[other_thing] => TTT
)
[7] => Array (
[tid] => 46
[date] => 1504594800
[thing] => 2J7248A
[other_thing] => shower
)
[8] => Array (
[tid] => 45
[date] => 1513238400
[thing] => 2J7348C
[other_thing] => TTT
)
)
That's what I'd like to do.
I'd like to sort this array.

You should consider using usort() (Docs). This function allows you to specify a comparator to have a user-defined sorting algorithm.
The resulting code might look like this:
function cmp($a, $b)
{
return $b['date'] - $a['date'];
}
usort($your_array, "cmp");

One fast forward solution would be to use the date as a key of the array while the array is being build and then you can simply sort keys using PHP ksort().
To avoid keys duplicity check if the key is set to handle such situations.
// building the data array from database or so
$array = array(); // the array to be sorted
$duplicity = array(); // track the duplicity date records
foreach ($data as $key => $value) {
$counter = 0;
#$duplicity[$value['date']]++; // suppressing notices
$array[$value['date'].'_'.$duplicity[$value['date']]] = $value;
}
ksort($array); // sort array by keys
print_r($array); // just check the sorted array
Demo: https://eval.in/978160
More sorting functions Sorting arrays

Related

PHP Combine multiple arrays of objects and change array structure

I have multiple separate arrays of objects that are imported (JSON-encoded) from MySQL that I need to merge and change structure. I basically need the combined [time] and [day] entries to be an array of [cycle] so I can loop over them. Currently after import/decoding the array of objects structure for each MySQL query looks like this:
(query 1)
stdClass Object
(
[day] => Array
(
[0] => stdClass Object
(
[day] => 1
[time] => 60
[name] => Running
[cycle] => 1
)
[1] => stdClass Object
(
[day] => 5
[time] => 30
[name] => Running
[cycle] => 1
)
)
[id] => 15359593
)
(query 2)
stdClass Object
(
[day] => Array
(
[0] => stdClass Object
(
[day] => 1
[time] => 55
[name] => Running
[cycle] => 2
)
[1] => stdClass Object
(
[day] => 5
[time] => 15
[name] => Running
[cycle] => 2
)
)
[id] => 36848901
)
The structure that need is:
stdClass Object
(
[day] => 1
[name] => Running
[cycle] => Array
(
[0] => stdClass Object
(
[time] => 60
[cycle] => 1
[day] => 1
)
[1] => stdClass Object
(
[time] => 55
[cycle] => 2
[day] => 1
)
)
[id] => 36848901
)
stdClass Object
(
[day] => 5
[name] => Running
[cycle] => Array
(
[0] => stdClass Object
(
[time] => 30
[cycle] => 1
[day] => 5
)
[1] => stdClass Object
(
[time] => 15
[cycle] => 2
[day] => 5
)
)
[id] => 1237465
)
I need the program to then iterate over the array using foreach [day] and then [cycle] to produce something like this:
name day cycle 1 cycle 2 cycle ..
Running 1 60 55 ..
Running 5 30 15 ..
..
It can only do it on a row by row basis. I don't have (much) control over this part of the process.
I have tried changing the structure by using foreach loops and array commands like this:
$newArray[] = array( "name" => $this->name, "day" => $this->day,
array("cycle" => $this->cycle, array("time" => $this->time, "cycle" =>
$this->cycle, "day" => $this->day)));
This gives me a structure that is almost right, per entry but not combined for all.
To combine them I've tried array_merge_recursive() and various variants but no luck.
So what I think I need is to merge the arrays of objects and then change the structure to have the values of each [time] and [day] to be nested inside the [cycle] so I can loop over them.
What is the best way to do this?
It is running on PHP 7.2.
More of my attempted code:
// get {data} part of JSON-encoded field for each mysql result
for ($x = 0; $x < $this->cycleCount; $x++) {
preg_match("/{.*}/",$this->tmpString[$x]['data'],$matches);
$this->data[$x] = json_decode($matches[0]);
foreach ($this->data[$x] as $day) {
$newArray[] = array( "name" => $day->name, "day" => $day->day,
array("cycle" => $day->cycle,
array("time" => $day->time,
"cycle" => $day->cycle,
"day" => $day->day)
)
);
}
$data = array();
$object = json_decode($querObject,true);
foreach($object as $day => $info)
{
foreach($info['cycle'] as $cycleInfo)
{
$data[$info['$id']]['name'] = $cycleInfo['name'];
$data[$info['$id']]['day'] = $cycleInfo['day'];
$data[$info['$id']]['id'] = $cycleInfo['id'];
$data[$info['$id']]['cycle'][] =array('time'=>$cycleInfo['time'],'cycle'=>$cycleInfo['cycle'],'day'=>=>$cycleInfo['day']);
}
}

Remove duplicate yyyy/mm from array

How I can remove duplicate entries based on Year and Month when my date format is YYYY-MM-DD? I tried removing days, but then I need to add the last day in the array, so my approach was wrong.
My array looks like this:
Array
(
[0] => Array
(
[id] => 9240399
[time] => 2018-01-01
[pages_indexed] => 942
)
[1] => Array
(
[id] => 9240322
[time] => 2018-01-02
[pages_indexed] => 940
)
[2] => Array
(
[id] => 9240344
[time] => 2018-01-03
[pages_indexed] => 947
)
[30] => Array
(
[id] => 9240344
[time] => 2018-01-31
[pages_indexed] => 947
)
[31] => Array
(
[id] => 9240344
[time] => 2018-02-01
[pages_indexed] => 1999
)
[32] => Array
(
[id] => 9240344
[time] => 2018-02-02
[pages_indexed] => 13339
)
Notice that I skipped some entries, so my dates are 2018-01-01, 2018-01-02, etc.
Array_unique would not work here since the day is different.
I tried this: ( $entries['time'] is like ex: 2018-01-01. )
$remove = DATE("Y-m",$entries['time']);
$entriesa = array_unique($remove);
$entries['time'] = $entriesa;
Well... you could loop through your results and index each key as the Year and Month, and then update this index with the row that fits the pattern, meaning you would only have the rows you expect (but you would only have the last reference of them).
Like this:
$expectedArray = [];
foreach ($arrayDuplicated as $item) {
$indexKey = substr($item['time'], 0, 7);
$expectedArray[$indexKey] = $item;
}

push to a multidimensional array in php

I have array that contain an score and id that calculated from other function
And I have user info that retried from DB.
In Both array ID's are the same
how can I push them to One array?
Score Array
Array
(
[0] => Array
(
[id] => 85
[total_cnt] => 2006
)
[1] => Array
(
[id] => 86
[total_cnt] => 1014
)
[2] => Array
(
[id] => 92
[total_cnt] => 6
)
[3] => Array
(
[id] => 93
[total_cnt] => 6
)
)
user info
Array
(
[0] => Array
(
[id] => 52
[user_phone] => 00000000
[user_email] => test#yahoo.com
[user_name] => yahoo
[user_picture] =>FG6K7Z3XTc.Pic.jpg
[user_post_hour] => 24
[user_is_block] => 1
[user_reg_date] => 2017-05-16 13:52:35
)
[1] => Array
(
[id] => 78
[user_phone] => 000000001
[user_email] => google#gmail.com
[user_name] => google
[user_picture] =>XqWKSDVci.Pic.jpg
[user_post_hour] => 24
[user_is_block] => 0
[user_reg_date] => 2017-05-16 13:52:35
)
)
My Desire output
Array
(
[0] => Array
(
[id] => 86 <--Same ID in both arrays
[user_phone] => 00000000
[user_email] => test#yahoo.com
[user_name] => yahoo
[user_picture] =>FG6K7Z3XTc.Pic.jpg
[user_post_hour] => 24
[user_is_block] => 1
[user_reg_date] => 2017-05-16 13:52:35
[total_cnt] => 1014 <-- first array field added
)
I want an optimized code and I won't use loop for to do this
Thanks for your help
Use PHP's built-in function array_merge. Use the official PHP documentation for additional guidance # http://php.net/manual/en/function.array-merge.php
Update:
A much better approach seems to be "array_column":
$cnts = array_column($scores, 'total_cnt', 'id');
foreach ($userInfo as $key => $item) {
$userInfo[$key]['total_cnt'] = $cnts[$item['id']];
}
I made some "naive" benchmark tests using microtime() and test data like your arrays:
Execution times:
10000 items in both arrays:
array_column 0.005s vs 0.85s foreach
20000 items in both arrays:
array_column 0.011s vs 18s foreach
Original answer:
You can also use foreach loops like this:
foreach ($userInfo as $userKey => $item) {
foreach ($scores as $scoreKey => $score) {
if ($score['id'] == $item['id']) {
$userInfo[$userKey]['total_cnt'] = $score['total_cnt'];
unset($scores[$scoreKey]);
break;
}
}
}
The unset within the second loop "removes" the processed score from the $scores array to reduce the number of iteration cycles in the next run. Please note that the $scores array will be empty afterwards, maybe create a copy of it and work with that.

Sort array PHP (Order array php)

This is my array () ...not much English'm using google translator.
I'm printing this array with print_r (). but what I deceo is sort of form this down
Array
(
[0] => Array
(
[0] => 606125999550609
[1] => Patricia
[2] => Michelle
)
[1] => Array
(
[0] => 724417787635260
[1] => Nasshy
[2] => Green
)
[2] => Array
(
[0] => 1121064174618668
[1] => Luisanna
[2] => Rodriguez
)
[3] => Array
(
[0] => 1057585894278115
[1] => Libane
[2] => Heredia
)
)
Basically what I need is to sort this array as follows......
So I do not know how to sort follows in PHP...
Array
(
[0] => 606125999550609
[1] => 724417787635260
[2] => 1121064174618668
[3] => 1057585894278115
[4] => Patricia
[5] => Nasshy
[6] => Luisanna
[7] => Libane
[8] => Michelle
[9] => Green
[10] => Rodriguez
[11] => Heredia
)
This isn't so much "sorting", its' more of a manipulation/restructure. Using a loop to regenerate your array would be the option, but if you can modify the data from where it comes from, then that's always recommended.
$new = array();
array_map(function($obj) use(&$new) {
foreach($obj as $i => $elem) {
$new[$i][] = $elem;
}
}, $array);
In the example above, we're using array_map() to apply our function() {... that runs the loop of each element, applying it to our $new array.
All you need to do is pass your $array in as you see above.
Example/Demo

How to merge these two arrays in this specific order

I have two array as following
Array
(
[0] => 641
[1] => 622
[2] => 100
[3] => 6431
)
Array
(
[0] => 64.1
[1] => 62.2
[2] => 10
[3] => 643.1
)
How can I make it as following
Array
(
[0] => 641
[1] => 64.1
[2] => 622
[3] => 62.2
[4] => 100
[5] => 10
[6] => 6431
[7] => 643.1
)
It's as simple as
$result=array_merge($array1,$array2);
Note: Your values wont be in the order you presented though. If that is important then you need to loop through your arrays to build a new array accordingly.
Ummm ok here is that version as well
if(count($array1)==count($array2))
{
for($i=0;$i<count($array1);$i++)
{
$result[]=$array1[$i];
$result[]=$array2[$i];
}
}
print_r($result);
Fiddle
Manual
you can use array_merge() function merges one or more arrays into one array.
example:
array_merge(array1,array2,array3...)

Categories