I'm new in PHP. I have reviewed some other threads about the array combination but I couldn't found the answer.
For example the first array
array (
'date' => '01.06.2019',
'day' => 'Saturday',
)
Second array
array (
0 =>
array (
'id' => 10,
'name' => 'Mj phooi',
),
)
Expected result
array (
'date' => '01.06.2019',
'day' => 'Saturday',
'id' => 10,
'name' => 'Mj phooi',
)
I did try the array_combine and array_merge_recursive but it doesn't work. The closure result I tried is like $result = array_merge($arr,$temp);. It combined two arrays but there have two arrays inside which not match with the expected result.
You are almost there, you could use array_merge but the array in the $temp is a nested array so you might take the first index 0:
$arr = [
'date' => '01.06.2019',
'day' => 'Saturday',
];
$temp = [
[
'id' => 10,
'name' => 'Mj phooi',
]
];
print_r(array_merge($arr, $temp[0]));
Result:
Array
(
[date] => 01.06.2019
[day] => Saturday
[id] => 10
[name] => Mj phooi
)
See a php demo
Note that an array can not have duplicate keys so if they have the same keys the last will override the existing key.
Related
I have an array in PHP and I need to sort by a nested array inside of the array...
Here is my array:
Array
(
[0] => Array
(
[project_id] => 1
[earnest_money_due] => Array
(
[value] => 1000.00,
[currency] => 'USD'
)
)
[1] => Array
(
[project_id] => 2
[earnest_money_due] => Array
(
[value] => 200.00,
[currency] => 'USD'
)
)
[2] => Array
(
[project_id] => 3
[earnest_money_due] => Array
(
[value] => 900.00,
[currency] => 'USD'
)
)
Here's how I'm trying to sort it:
$records - this the array of records
$column - this is the the sortable column "earnest_money_due"
$columns = array_column($records, $column);
array_multisort($columns, SORT_ASC, $records);
I need to be able to sort by the [value] of the [earnest_money_due]. My code doesn't work because it's trying to sort an array, not a value.
Try this...
<?php
$array = [
[
'project_id' => 1,
'earnest_money_due' => [
'value' => 1000.00,
'currency' => 'USD',
],
],
[
'project_id' => 2,
'earnest_money_due' => [
'value' => 200.00,
'currency' => 'USD',
],
],
[
'project_id' => 3,
'earnest_money_due' => [
'value' => 900.00,
'currency' => 'USD',
],
],
];
array_multisort(
array_map(
static function ($element) {
return $element['earnest_money_due']['value'];
},
$array
),
SORT_ASC,
$array
);
var_dump($array);
If you remove the SORT_ASC, then your code works just fine. This is because PHP will sort your subarray as expected with it removed. It will compare from the start of the subarray. (Demo)
array_multisort(array_column($array, 'earnest_money_due'), $array);
If that seems too hacky, unreliable, or unintuitive, array_map() is fine. (Demo)
array_multisort(array_map(fn($row) => $row['earnest_money_due']['value'], $array), $array);
There is also nothing wrong with using usort(). (Demo)
usort($array, fn($a, $b) => $a['earnest_money_due']['value'] <=> $b['earnest_money_due']['value']);
Regardless of which array_multsort() technique you use, you don't need to explicitly use SORT_ASC because this is the default sorting order.
I have two array:
One Array
$workingDays = ['2019-11-01','2019-11-02','2019-11-03','2019-11-04'];
Other Array
$doneWork = array(
array(
'id' => 1,
'date' => '2019-11-01',
'work' => 'done'
),
array(
'id' => 1,
'date' => '2019-11-02',
'work' => 'done'
),
array(
'id' => 1,
'date' => '2019-11-04',
'work' => 'done'
)
);
My Question: How can check which date not exist in $doneWork array
You'd start by extracting the dates from $doneWork using array_map.
$doneWork = [
[
'id' => 1,
'date' => '2019-11-01',
'work' => 'done',
],
[
'id' => 1,
'date' => '2019-11-02',
'work' => 'done',
],
[
'id' => 1,
'date' => '2019-11-04',
'work' => 'done',
],
];
$doneWorkDays = array_map(function ($element) {
return $element['date'];
}, $doneWork);
print_r($doneWorkDays);
Will print:
Array ( [0] => 2019-11-01 [1] => 2019-11-02 [2] => 2019-11-04 )
Then check which elements in $workingDays are not in such array, using array_diff
$diff = array_diff($workingDays, $doneWorkDays);
print_r($diff);
Will print:
Array ( [2] => 2019-11-03 )
Pay attention, the result gives you not only the elements but also their index in the original array. If you don't care about these, use instead:
print_r(array_values($diff));
Why would anyone need such index? Well, perhaps you could need to report not only how many days were missed but also check if two missing elements are adjacent.
(the indexes are relevant only for the array you're comparing against. It doesn't matter in what position they appear in $doneWork )
Edit:
You say you need the results to be in "doneWork" format, which is an associative array with id (always zero), date and work (always 'absent').
Let's say your workin days are now
$workingDays = [
'2019-11-01',
'2019-11-02',
'2019-11-03',
'2019-11-04',
'2019-11-05'
];
So there are two missing days. Again, array map to the rescue:
// from previous answer
$diff = (array_diff($workingDays, $doneWorkDays));
// map each missing date to a doneWork array
$diff_assoc = array_values(
array_map(function($date) {
return [
'id' => 0,
'date' => $date,
'work' => 'absent'
];
},$diff)
);
That will return
Array
(
[0] => Array
(
[id] => 0
[date] => 2019-11-03
[work] => absent
)
[1] => Array
(
[id] => 0
[date] => 2019-11-05
[work] => absent
)
)
Again, note I'm wrapping the result in array_values because you need a plain array as result instead of:
Array
(
[2] => Array
(
[id] => 0
[date] => 2019-11-03
[work] => absent
)
[4] => Array
(
[id] => 0
[date] => 2019-11-05
[work] => absent
)
)
$nonExistingDates = [];
$doneWorkDays = [];
foreach($doneWork as $work) {
$doneWorkDays[] = $work['date'];
}
$nonExistingDates = array_diff($workingDays, $doneWorkDays);
// optional, removes duplicate dates
$nonExistingDates = array_unique($nonExistingDates);
If I var_export I get
array (
0 =>
array (
'date' => 2017,
'id' => 128343,
),
1 =>
array (
'date' => 1976,
'id' => 128315,
),
2 =>
array (
'date' => 2006,
'id' => 128310,
),
3 =>
array (
'date' => 1967,
'id' => 128304,
),
4 =>
array (
'date' => 1938,
'id' => 128295,
),
5 =>
array (
'date' => 1978,
'id' => 128293,
),
6 =>
array (
'date' => 1997,
'id' => 128157,
),
7 =>
array (
'date' => 2000,
'id' => 128124,
),
The dates are mixed up. I am trying to sort those dates and keep the Ids attached to each date DESC in order then to loop again but ordered. I tried
function custom_sort_dt($a, $b) {
return $a['date'] - $b['date'];
}
usort($dateOrdered, "custom_sort_dt");
But I still get wrong order.
// the following gives a date
$myDate = (int)get_post_meta($id, 'usp-custom-14', true);
// this attaches the Id and the date
$dateOrdered[] = array("date"=>$myDate, "id"=>$id);
You could use array_multisort.
array_multisort($data, SORT_DESC, array_column($data, 'date'));
var_dump($data);
Note that this function operates on the original array. If you want a copy instead, build one before by
$copy = $data;
Perhaps try reversing the comparison to sort in descending order:
return $b['date'] - $a['date'];
I have a multidimensional array in php:
Array (
[0] => Array (
[certificate_name] => track.site
[domains] => track.site
[expiry_date] => Array (
[date] => 2018-09-25
[time] => 10:11:58
[count] => (22)
)
)
[1] => Array (
[certificate_name] => stats.com
[domains] => stats.com
[expiry_date] => Array (
[date] => 2018-09-24
[time] => 10:11:58
[count] => (43)
)
)
)
I want to sort this multidimensional array by $array['expiry_date']['count']
This can be done with usort:
$data = [
[
'certificate_name' => 'track.site',
'domains' => 'track.site',
'expiry_date' => [
'date' => '2018-09-25',
'time' => '10:11:58',
'count' => 22,
]
],
[
'certificate_name' => 'stats.com',
'domains' => 'stats.com',
'expiry_date' => [
'date' => '2018-09-24',
'time' => '10:11:58',
'count' => 43,
]
]
];
function compare_by_expiry_date_count($a, $b) {
return $a["expiry_date"]['count'] > $b["expiry_date"]['count'];
}
usort($data, "compare_by_expiry_date_count");
var_dump($data);
If I don't misunderstood your question then you need sorting by count not filtering. Also use trim() to remove parenthesis from the count value. Hope it helps :)
Try like this way, $b-$a is for desc, $a-$b is for asc
<?php
// this $b-$a is for desc, for asc try $a-$b
function sorting_by_count($a, $b)
{
return trim($b['expiry_date']['count'],'()') - trim($a['expiry_date']['count'],'()');
}
$array = [
[
'certificate_name' => 'track.site',
'domains' => 'track.site',
'expiry_date' => [
'date' => '2018-09-25',
'time' => '10:11:58',
'count' => '(22)',
]
],
[
'certificate_name' => 'stats.com',
'domains' => 'stats.com',
'expiry_date' => [
'date' => '2018-09-24',
'time' => '10:11:58',
'count' => '(43)',
]
]
];
usort($array, 'sorting_by_count');
print_r($array);
?>
DEMO: https://3v4l.org/vtRIu
For best time complexity, loop through your rows and populate a flat array containing the count values after trimming the parentheses and casting to an integer.
Then call array_multisort() with the counts array as the first argument and the original array as the second argument.
Code: (Demo)
foreach ($array as $row) {
$counts[] = (int) trim($row['expiry_date']['count'], '()');
}
array_multisort($counts, $array);
var_export($array);
Using usort() and calling trim() on every iteration will be more expensive because it will have to re-trim values that were already encountered.
How to extract unique values from this array.
I've tried another suggestion...
$input = array_map("unserialize", array_unique(array_map("serialize", $input)));
However because of the unix timestamp it wont work.
Im looking to extract only the second array index unique value and its array so should be left with..
// expected final
array(
2 => array(...),
3 => array(..)
)
$arr = array (
0 =>
array (
2 =>
array (
'date' => 1438173658,
'user' => 'admin',
),
),
1 =>
array (
2 =>
array (
'date' => 1438007944,
'user' => 'admin',
),
),
2 =>
array (
3 =>
array (
'date' => 1437746969,
'user' => 'supes',
),
)
)
Thanks.
Might be a simpler way, but here is one:
$result = array_intersect_key($arr,
array_unique(array_map(function($v) {
return current($v)['user'];
},
$arr)));