My array is like so:
[
['name' => 'abc-def-12', 'qty' => 250, 'sub_qty' => '1385', 'Location' => 'NOP01'],
['name' => 'abc-def-23', 'qty' => 1234, 'sub_qty' => '615, 101, 432, 116', 'Location' => 'NOP10, NOP04, NOP08, NOP06'],
['name' => 'abc-def-34', 'qty' => 379, 'sub_qty' => 62, 'Location' => 'NOP08'],
['name' => 'abc-def-45', 'qty' => 425, 'sub_qty' => '372, 89', 'Location' => 'NOP07, NOP05'],
['name' => 'abc-def-56', 'qty' => 0],
['name' => 'abc-def3.FMF', 'qty' => 523, 'sub_qty' => '240, 103, 180', 'Location' => 'NOP06, NOP08, NOP11'],
]
I'm having issues sorting the array where abc-def3.FMF comes before abc-def-12. This is after I've sorted the array using:
function sortNames($a, $b){
return strcmp ($a['name'], $b['name']);
}
which prevent the names from lining up like so: abc-def-12, abc-def-23, abc-def3.FMF, abc-def-34, abc-def-45, abc-def-56
How might I achieve my goal so the array prints like:
[
['name' => 'abc-def3.FMF', 'qty' => 523, 'sub_qty' => '240, 103, 180', 'Location' => 'NOP06, NOP08, NOP11'],
['name' => 'abc-def-12', 'qty' => 250, 'sub_qty' => '1385', 'Location' => 'NOP01'],
['name' => 'abc-def-23', 'qty' => 1234, 'sub_qty' => '615, 101, 432, 116', 'Location' => 'NOP10, NOP04, NOP08, NOP06'],
['name' => 'abc-def-34', 'qty' => 379, 'sub_qty' => 62, 'Location' => 'NOP08'],
['name' => 'abc-def-45', 'qty' => 425, 'sub_qty' => '372, 89', 'Location' => 'NOP07, NOP05'],
['name' => 'abc-def-56', 'qty' => 0],
]
Because version_compare() replaces hyphens with dots, it appears to be adequate for sorting your provided sample data.
Code: (Demo)
usort($array, fn($a, $b) => version_compare($a['name'], $b['name']));
var_export($array);
Related
This question already has answers here:
Sort array using array_multisort() with dynamic number of arguments/parameters/rules/data
(5 answers)
Closed last month.
I'm using array_multisort (PHP 7.4) to apply a mutli-dimensional sort. I think I'm using it correctly, but the result is not what I would expect. No matter what direction I set, it only sorts ascending (even if I set both to SORT_DESC). I tried different sort flags (e.g. SORT_STRING, SORT_NATURAL), but this did not make a difference.
$definitions = [
[
'name' => 'Bart',
'age' => 12,
'location' => 'Brazil',
],
[
'name' => 'Daniel',
'age' => 51,
'location' => 'Brazil',
],
[
'name' => 'Adam',
'age' => 33,
'location' => 'France',
],
[
'name' => 'Adam',
'age' => 44,
'location' => 'France',
],
[
'name' => 'Adam',
'age' => 5,
'location' => 'France',
],
[
'name' => 'Zed',
'age' => 21,
'location' => 'GB',
],
];
$sorting = [
[
'field' => 'name',
'direction' => SORT_ASC,
],
[
'field' => 'age',
'direction' => SORT_DESC,
]
];
$sort_args = [];
foreach ($sorting as $sort) {
$sort_args[] = array_column($definitions, $sort['field']);
$sort_args[] = $sort['direction'];
$sort_args[] = SORT_REGULAR;
}
array_multisort($definitions, ...$sort_args);
The result:
array (
0 =>
array (
'name' => 'Adam',
'age' => 5,
'location' => 'France',
),
1 =>
array (
'name' => 'Adam',
'age' => 33,
'location' => 'France',
),
2 =>
array (
'name' => 'Adam',
'age' => 44,
'location' => 'France',
),
3 =>
array (
'name' => 'Bart',
'age' => 12,
'location' => 'Brazil',
),
4 =>
array (
'name' => 'Daniel',
'age' => 51,
'location' => 'Brazil',
),
5 =>
array (
'name' => 'Zed',
'age' => 21,
'location' => 'GB',
),
)
What I expected:
array (
0 =>
array (
'name' => 'Adam',
'age' => 44,
'location' => 'France',
),
1 =>
array (
'name' => 'Adam',
'age' => 33,
'location' => 'France',
),
2 =>
array (
'name' => 'Adam',
'age' => 5,
'location' => 'France',
),
3 =>
array (
'name' => 'Bart',
'age' => 12,
'location' => 'Brazil',
),
4 =>
array (
'name' => 'Daniel',
'age' => 51,
'location' => 'Brazil',
),
5 =>
array (
'name' => 'Zed',
'age' => 21,
'location' => 'GB',
),
)
Am I missing something or is this busted?
You have the arguments in the wrong order. The array you wish to sort should be the last item for this type of sorting.
Example #3: https://www.php.net/manual/en/function.array-multisort.php#example-5040
You may have done this so that you can use the spread operator (which is fine). If you want to continue using the spread operator you would adjust your code as so:
$sort_args[] = &$definitions; // add this line
array_multisort(...$sort_args); // remove `$definitions` from this line
Note that we are passing $definitions as reference otherwise when we push it to $sort_args, we would be creating a copy (due to the nature of PHP).
Without passing by reference, that original array won't be sorted, only the copy we created.
I have been given a dataset by my tutor and asked to carry out the following:
// make a function
// get skus of which the figure of the average monthly sales unit is equal or greater than 350
// array in the following format:
[
'id' => 11102,
'sku' => 'TEST_3',
'alternates' => [
'asin' => [
'code' => '50',
'value' => 'JL1235',
],
'barcode' => [
'code' => '10',
'value' => 'JS160694',
],
],
'commodityCode' => '9989898889',
'price' => [
'value' => 145.99,
],
'instructions' => [
'picking' => [
'code' => 'PICK',
'value' => 'I\'VE JUST HAD AN UNHAPPY LOVE AFFAIR, SO I DON\'T SEE WHY ANYBODY ELSE SHOULD HAVE A GOOD TIME.',
],
],
'quantity' => [
'inner' => 100,
'masterCarton' => 200,
'pallet' => 300,
],
'averageMonthlyUnitSales' => 100,
'created_at' => '2022-03-13 04:14:12'
],
Example dataset is here:
$data = [
[
'id' => '9947',
'sku' => 'test_1',
'asin_code' => '50',
'asin_value' => '',
'barcode' => '10',
'barcode_value' => 'js160694',
'commodityCode' => '9989898889',
'price' => '120.50',
'picking_instruction_code' => 'PICK',
'picking_instruction_value' => '',
'qty_inner' => '120',
'qty_masterCarton' => '200',
'qty_pallet' => '1200',
'averageMonthlyUnitSales' => '750',
'created_at' => '2019-02-23T01:54:14.957299+00:00'
],
[
'id' => '10921',
'sku' => 'test_2',
'asin_code' => '50',
'asin_value' => 'bx12345',
'barcode' => '10',
'barcode_value' => 'jb170931',
'commodityCode' => '9989898889',
'price' => '20.59',
'picking_instruction_code' => 'PICK',
'picking_instruction_value' => 'It\'s only half completed, I\'m afraid',
'qty_inner' => '70',
'qty_masterCarton' => '250',
'qty_pallet' => '270',
'averageMonthlyUnitSales' => '120',
'created_at' => '2021-12-23T11:41:31.193982+00:00'
],
[
'id' => '11102',
'sku' => 'test_3',
'asin_code' => '50',
'asin_value' => 'jl1235',
'barcode' => '10',
'barcode_value' => 'js160694',
'commodityCode' => '9989898889',
'price' => '145.99',
'picking_instruction_code' => 'PICK',
'picking_instruction_value' => 'I\'ve just had an unhappy love affair, so I don\'t see why anybody else should have a good time.',
'qty_inner' => '100',
'qty_masterCarton' => '200',
'qty_pallet' => '300',
'averageMonthlyUnitSales' => '100',
'created_at' => '2022-03-13T04:14:12.11.093745 +00:00'
],
];
I can perform the first part of the assignment (filter for averageMonthlyUnitSales>350) by carrying out something like:
$filtered_array= array_filter($data, function($item){
return ($item['averageMonthlyUnitSales']>350);
});
But I am not too sure how I can go about getting a new array in the required format?
The only way I can see to simply do both is as follows.
$data = [
[
'id' => '9947',
'sku' => 'test_1',
'asin_code' => '50',
'asin_value' => '',
'barcode' => '10',
'barcode_value' => 'js160694',
'commodityCode' => '9989898889',
'price' => '120.50',
'picking_instruction_code' => 'PICK',
'picking_instruction_value' => '',
'qty_inner' => '120',
'qty_masterCarton' => '200',
'qty_pallet' => '1200',
'averageMonthlyUnitSales' => '750',
'created_at' => '2019-02-23T01:54:14.957299+00:00'
],
[
'id' => '10921',
'sku' => 'test_2',
'asin_code' => '50',
'asin_value' => 'bx12345',
'barcode' => '10',
'barcode_value' => 'jb170931',
'commodityCode' => '9989898889',
'price' => '20.59',
'picking_instruction_code' => 'PICK',
'picking_instruction_value' => 'It\'s only half completed, I\'m afraid',
'qty_inner' => '70',
'qty_masterCarton' => '250',
'qty_pallet' => '270',
'averageMonthlyUnitSales' => '120',
'created_at' => '2021-12-23T11:41:31.193982+00:00'
],
[
'id' => '11102',
'sku' => 'test_3',
'asin_code' => '50',
'asin_value' => 'jl1235',
'barcode' => '10',
'barcode_value' => 'js160694',
'commodityCode' => '9989898889',
'price' => '145.99',
'picking_instruction_code' => 'PICK',
'picking_instruction_value' => 'I\'ve just had an unhappy love affair, so I don\'t see why anybody else should have a good time.',
'qty_inner' => '100',
'qty_masterCarton' => '200',
'qty_pallet' => '300',
'averageMonthlyUnitSales' => '100',
'created_at' => '2022-03-13T04:14:12.11.093745 +00:00'
],
];
$new = [];
foreach ($data as $line){
if ( $line['averageMonthlyUnitSales'] > 350 ){
// reformat the array
$new = [
'id' => $line['id'],
'sku' => $line['sku'],
'alternates' => ['asin' => ['code'=>$line['asin_code'], 'value'=>$line['asin_value'] ],
'barcode' => ['code'=> $line['barcode'], 'value' => $line['barcode_value']]
],
'commodityCode' => $line['commodityCode'],
'price' => [ 'value' => $line['price'] ],
'instructions' => ['picking' => ['code' => $line['picking_instruction_code'], 'value'=> $line['picking_instruction_value']]
],
'quantity' =>['inner' =>$line['qty_inner'], 'masterCarton' =>$line['qty_masterCarton'], 'pallet'=>$line['qty_pallet']],
'averageMonthlyUnitSales'=>$line['averageMonthlyUnitSales'],
'created_at'=>$line['averageMonthlyUnitSales']
];
}
}
print_r($new);
RESULT
PHP 8.1.3
Array
(
[id] => 9947
[sku] => test_1
[alternates] => Array
(
[asin] => Array
(
[code] => 50
[value] =>
)
[barcode] => Array
(
[code] => 10
[value] => js160694
)
)
[commodityCode] => 9989898889
[price] => Array
(
[value] => 120.50
)
[instructions] => Array
(
[picking] => Array
(
[code] => PICK
[value] =>
)
)
[quantity] => Array
(
[inner] => 120
[masterCarton] => 200
[pallet] => 1200
)
[averageMonthlyUnitSales] => 750
[created_at] => 750
)
I have the following array:
$products = [
[
'id' => 21,
'name' => 'Floral Dress',
'params' => [
'size' => 14,
'price' => 23.99,
'department' => 'Dresses'
]
],
[
'id' => 413,
'name' => 'Maxi Skirt',
'params' => [
'size' => 10,
'price' => 12.99,
'department' => 'Skirts'
]
],
[
'id' => 78,
'name' => 'A Line Prom Dress',
'params' => [
'size' => 10,
'price' => 79.99,
'department' => 'Dresses'
]
],
[
'id' => 212,
'name' => 'Nude Block High Heels',
'params' => [
'size' => 6,
'price' => 20.99,
'department' => 'Shoes'
]
],
[
'id' => 54,
'name' => 'Denim Trim Dress',
'params' => [
'size' => 8,
'price' => 52.99,
'department' => 'Dresses'
]
],
];
Unfortunately I cannot control how the array is built.
Instead I need to restructure the data so that the array is sorted by the ['params']['department'] key.
So ideally I would take the above and output it like so:
$products = [
'Dresses' => [
[
'id' => 21,
'name' => 'Floral Dress',
'params' => [
'size' => 14,
'price' => 23.99
]
],
[
'id' => 78,
'name' => 'A Line Prom Dress',
'params' => [
'size' => 10,
'price' => 79.99
]
],
[
'id' => 54,
'name' => 'Denim Trim Dress',
'params' => [
'size' => 8,
'price' => 52.99
]
],
],
'Skirts' => [
[
'id' => 413,
'name' => 'Maxi Skirt',
'params' => [
'size' => 10,
'price' => 12.99
]
],
],
'Shoes' => [
[
'id' => 212,
'name' => 'Nude Block High Heels',
'params' => [
'size' => 6,
'price' => 20.99
]
],
]
You could simply iterate over all the products and populate a new associative array holding the departments, which are themselves arrays of corresponding products. See the comments in the code below.
<?php
// same data as in the question, just in one line for better overview
$products = [['id' => 21,'name' => 'Floral Dress','params' => ['size' => 14,'price' => 23.99,'department' => 'Dresses']],['id' => 413,'name' => 'Maxi Skirt','params' => ['size' => 10,'price' => 12.99,'department' => 'Skirts']],['id' => 78,'name' => 'A Line Prom Dress','params' => ['size' => 10,'price' => 79.99,'department' => 'Dresses']],['id' => 212,'name' => 'Nude Block High Heels','params' => ['size' => 6,'price' => 20.99,'department' => 'Shoes']],['id' => 54,'name' => 'Denim Trim Dress','params' => ['size' => 8,'price' => 52.99,'department' => 'Dresses']]];
// initialize empty department array
$departments = array();
// iterate over all the products
foreach ( $products as $product ) {
// get this product's department
$product_department = $product['params']['department'];
// unset the department in the params array
unset( $product['params']['department'] );
// initialize this department as an empty array
// if it doesn't exist yet
if ( !isset( $departments[$product_department] ) ) {
$departments[$product_department] = array();
}
// push this product in its corresponding department
$departments[$product_department][] = $product;
}
var_dump( $departments );
$groupedProducts = [];
foreach ($products as &$product) {
$department = $product['params']['department'];
unset($product['params']['department']);
$groupedProducts[$department] = $product;
}
var_dump($groupedProducts);
I have just finished creating this beautiful php object tree. How would I go about inserting new objects using a loop into the items node array? Basically how do I insert new anonymous item objects into the items array in this object tree?
Take a look
<?php
$phpObjectTree =
(object)[
'apiVersion' => '1.0',
'data' => (object)[
'requested' => '2020-01-01T23:59:59.001Z',
'status' => 'OK',
'estimate' => (object)[
'id' => '1001',
'type' => 'Commercial',
'client' => (object)[
'name' => 'ABC Construction, Inc.',
'address1' => '123 Main St',
'city' => 'Salt Lake City',
'state' => 'UT',
'postalCode' => '84101'
],
'summary' => (object)[
'generalRequirements' => (object)[
'default' => 0
],
'salesTax' => (object)[
'material' => 4.85,
'labor' => 4.85,
'equipment' => 4.85
],
'overheadProfit' => (object)[
'material' => 10,
'labor' => 10,
'equipment' => 10
],
'contingency' => (object)[
'default' => 3
],
'performanceBond' => (object)[
'default' => 1.3
],
'laborPlus' => (object)[
'dailyRate' => 280,
'crewCount' => 0,
'dayCount' => 0
],
'locationAdjustment' => (object)[
'factor' => 90.1
],
]
],
'items' => [
(object)[
'id' => '2001',
'number' => '09 91 23.00 0000',
'description' => 'Line Item 1',
'quantity' => 0,
'unit' => 'sf',
'material' => (object)[
'cost' => 0,
'costEach' => 9.99
],
'labor' => (object)[
'cost' => 0,
'costEach' => 9.99
],
'equipment' => (object)[
'cost' => 0,
'costEach' => 9.99
],
'lineTotal' => 0
],
(object)[
'id' => '2002',
'number' => '09 91 23.00 0000',
'description' => 'Line Item 2',
'quantity' => 0,
'unit' => 'sf',
'material' => (object)[
'cost' => 0,
'costEach' => 9.99
],
'labor' => (object)[
'cost' => 0,
'costEach' => 9.99
],
'equipment' => (object)[
'cost' => 0,
'costEach' => 9.99
],
'lineTotal' => 0
]
]
]
];
// SET JSON HEADER...
header('Content-type:application/json;charset=utf-8');
print_r(json_encode($phpObjectTree));
?>
Same way you'd modify any array in php:
https://www.php.net/manual/en/language.types.array.php#language.types.array.syntax.modifying
$phpObjectTree->data->items[] = (object)[
'id' => '2003',
'number' => '09 91 23.00 0000',
'description' => 'Line Item 3',
'quantity' => 0,
'unit' => 'sf',
'material' => (object)[
'cost' => 0,
'costEach' => 9.99
],
'labor' => (object)[
'cost' => 0,
'costEach' => 9.99
],
'equipment' => (object)[
'cost' => 0,
'costEach' => 9.99
],
'lineTotal' => 0
];
Or you can use stdClass to create new object and add properties.
$obj = new \stdClass;
$obj->newProperty = 'value';
Hi I'm have recursion function that makes binary tree array, so from that
array(
array(
'name' => 'John',
'id' => 1,
'mother_id' => 2,
'father_id' => 3
),
array(
'name' => 'Lucy',
'id' => 2,
'mother_id' => 5,
'father_id' => 4
),
array(
'name' => 'Jim',
'id' => 3,
'mother_id' => 7,
'father_id' => 9
),
array(
'name' => 'Paul',
'id' => 4,
'mother_id' => 534,
'father_id' => 54
),
array(
'name' => 'Laura',
'id' => 5,
'mother_id' => 554,
'father_id' => 51
),
array(
'name' => 'Vanessa',
'id' => 7,
'mother_id' => 5354,
'father_id' => 514
),
array(
'name' => 'Adam',
'id' => 9,
'mother_id' => 245354,
'father_id' => 514234
),
);
I'm getting that:
array(
array(
'person' => array(
'name' => 'John',
'id' => 1,
'mother_id' => 2,
'father_id' => 3
),
'parents' => array(
'mother' => array(
'person' => array(
'name' => 'Lucy',
'id' => 2,
'mother_id' => 5,
'father_id' => 4
),
'parents' => array(
'mother' => array(
'person' => array(
'name' => 'Laura',
'id' => 5,
'mother_id' => 554,
'father_id' => 51
),
'parents' => array(...)
),
'father' => array(
'person' => array(
'name' => 'Paul',
'id' => 4,
'mother_id' => 534,
'father_id' => 54
),
'parents' => array(...)
),
)
),
'father' => ...
)
and it works completely fine until it gets array with more than -+100 values, and when it gets this array, it returns 500 error, that's seems strange for me, cos obviously I don't have infinite loop or something like that, cos smallest arrays parses fine but I can't figure out what's reason for this kind of behavior.
function parseTree(&$tree, $root = null)
{
$return = null;
foreach ($tree as $key => $item) {
if ($root == null || $item['id'] == $root) {
$return = [
'person' => $item,
'parents' => [
'father' => parseTree($tree, $item['father_id']),
'mother' => parseTree($tree, $item['mother_id'])
]
];
unset ($tree[$key]);
}
}
return $return;
}