Fill array n-in-n values in PHP - php

For instance, I have an array with N elements, and I need that it have M elements where M is multiple of O. Example:
[signature: array array_fill_multiple(array, int o, mixed filler = null)]
$array = [ 1, 2 ];
array_fill_multiple($array, 1); // => [ 1, 2 ]
array_fill_multiple($array, 2); // => [ 1, 2 ]
array_fill_multiple($array, 3); // => [ 1, 2, null ]
array_fill_multiple($array, 4); // => [ 1, 2, null, null ]
$array = [ 1, 2, 3 ];
array_fill_multiple($array, 1); // => [ 1, 2, 3 ]
array_fill_multiple($array, 2); // => [ 1, 2, 3, null ]
array_fill_multiple($array, 3); // => [ 1, 2, 3 ]
array_fill_multiple($array, 4); // => [ 1, 2, 3, null ]
$array = [ 1, 2, 3, 4 ];
array_fill_multiple($array, 5, 0); // => [ 1, 2, 3, 4, 0 ]
I can do it with a for, but I guess that using native methods are possible, are not?
Edit
To explain better what I want, it need result in an array with multiples of O elements. So if I like that this array contains multiples of 5, it need result in an array with 0, 5, 10, 15, 20, 25... elements (zero included, if empty).
If my array have 15 elements, and I expect multiple of 2, it'll fit to next multiple of 2 after or equal 15, or be, 16. So only 1 padding will be created.
If my array have 3 elements and I expect multiple of 5, it'll fit to next multiple of 5, after or equal to 3, or be, the own 5. So 2 paddings will be created.
If my array have 10 elements and I expect multiple of 10, it'll fit to next multiple of 10, after or igual to 10, or be, the own 10. So none padding will be created, because my array yet is multiple of 10.
If my array is empty, it'll return an empty array.
I guess that array_pad() will help. Just need calculate the second argument to know what is the next multiple of O based on array count.

Something like this
$a = [1, 2, 3];
$multiple = 5;
$size = sizeof($a);
// first way
var_dump(array_pad($a, ceil($size / $multiple) * $multiple, null));
// second way
var_dump(array_pad($a, $size + ($size % $multiple ? $multiple - $size % $multiple : 0), null));
Second one is more accurate than first one. Let's suppose that you have array with 10000000000000001 items (on 64 system). Now you have to pad with multiplier 11.
$size = 10000000000000001 * 11;
$multiple = 11;
var_dump($size);
// int(110000000000000011)
// first way
ini_set('precision', 18);
var_dump(ceil($size / $multiple) * $multiple);
// double(110000000000000000)
// second way
var_dump($size + ($size % $multiple ? $multiple - $size % $multiple : 0));
// int(110000000000000011)
Now you see that first way produces wrong value because float values has less precision than int.

Basically you just replace "array_fill_multiple" with "array_pad" and it'll work :)
$array = [ 1, 2 ];
array_pad($array, 1, null); // => [ 1, 2 ]
array_pad($array, 2, null); // => [ 1, 2 ]
array_pad($array, 3, null); // => [ 1, 2, null ]
array_pad($array, 4, null); // => [ 1, 2, null, null ]
$array = [ 1, 2, 3 ];
array_pad($array, 1, null); // => [ 1, 2, 3 ]
array_pad($array, 2, null); // => [ 1, 2, 3, null ]
array_pad($array, 3, null); // => [ 1, 2, 3 ]
array_pad($array, 4, null); // => [ 1, 2, 3, null ]
$array = [ 1, 2, 3, 4 ];
array_pad($array, 5, 0); // => [ 1, 2, 3, 4, 0 ]

Related

PHP sum array value based on textual duplicate in another array

I have two arrays, both will always be the same count length. One has doubles mixed with integers, the second has textual (string only) values. They do correlate so I need them both to stay in order. Sorry no keys to work with (by design).
I need to sum the values where I have duplicates in the array that has strings.
Example
$dataLabelGraph = array(3, 8, 1, 4.85, 1, 0.5, 6.01, 7);
$dataCalcGraph = array("Coding", "Web development - Coding", "Meeting", "Coding", "Coding", "Content", "Coding", "Coding");
So my algorithm should look like this after
$dataLabelGraph = array(21.86, 8, 1, 0.5);
$dataCalcGraph = array("Coding", "Web development - Coding", "Meeting", "Content");
I was trying to adapt this solution, from the awesome brain of Martin D. # https://stackoverflow.com/a/22071693/12835769
$records_array = array("Coding", "Web development - Coding", "Meeting", "Coding", "Coding", "Content", "Coding");
$quantities_array = array(3, 8, 1, 4.85, 1, 0.5, 6.01, 7);
$new_array = array();
foreach ($records_array as $record_position => $new_array_key){
$new_array[$new_array_key] += $quantities_array[$record_position];
}
var_dump($new_array);
Gives something like this, which is close but I need them to remain in two separate arrays
array (size=4)
'Coding' => float 21.86
'Web development - Coding' => int 8
'Meeting' => int 1
'Content' => float 0.5
Any help to get me over the line would be immensely helpful. Kudos.
Group by the "name" and sum as you iterate. When the loop is finished, split the keys and the values into separate arrays.
Code: (Demo)
$records = [
"Coding",
"Web development - Coding",
"Meeting",
"Coding",
"Coding",
"Content",
"Coding",
"Coding"
];
$quantities = [
3,
8,
1,
4.85,
1,
0.5,
6.01,
7
];
$result = [];
foreach ($records as $index => $label){
$result[$label] = ($result[$label] ?? 0) + $quantities[$index];
}
var_export(array_keys($result));
var_export(array_values($result));
Outputs:
array (
0 => 'Coding',
1 => 'Web development - Coding',
2 => 'Meeting',
3 => 'Content',
)
array (
0 => 21.86,
1 => 8,
2 => 1,
3 => 0.5,
)

PHP Checkif two arrays have the same keys and same count of keys [duplicate]

This question already has answers here:
PHP - Check if two arrays are equal
(19 answers)
Check if two arrays have the same values (regardless of value order) [duplicate]
(13 answers)
How to check if PHP associative arrays are equal, ignoring key ordering?
(1 answer)
Closed 4 years ago.
I'm trying to match 2 arrays that look like below.
$system = array('blue' => 1, 'red' => 2, 'green' => 3, 'purple' => 4);
$public = array('blue' => 1, 'red' => 2, 'green' => 3, 'purple' => 4);
My problem is, I need the array keys of both arrays to be the same value and same count.
Which means:
// passes - both arrays have the same key values and same counts of each key
$system = array('blue' => 1, 'red' => 2, 'green' => 3, 'purple' => 4);
$public = array('blue' => 1, 'red' => 2, 'green' => 3, 'purple' => 4);
// fails - $public does not have 'blue' => 1
$system = array('blue' => 1, 'red' => 2, 'green' => 3, 'purple' => 4);
$public = array('red' => 2, 'green' => 3, 'purple' => 4);
// should fail - $public has 2 'blue' => 1
$system = array('blue' => 1, 'red' => 2, 'green' => 3, 'purple' => 4);
$public = array('blue' => 1, 'blue' => 1, 'red' => 2, 'green' => 3, 'purple' => 4);
I've tried using array_diff_keys, array_diff and other php functions, but none can catch extra keys with the same value (i.e. if 'blue' => 1, is repeated it still passes)
What's a good way to solve this?
When you write two values with same key in PHP, the second one will overwrite the value from the first (and this is not an error). Below is what I did on the PHP interactive CLI (run it with php -a):
php > $x = ["x" => 1, "x" => 2, "y" => 2];
php > var_dump($x);
array(2) {
["x"]=>
int(2)
["y"]=>
int(2)
}
So array_diff seems to be working correctly. You are just expecting PHP to behave in a different way than it actually does!

How to store different single array to database?

I have two arrays which I can get after form submit:
$product_id = $request->get('product_id');
// [1, 3, 4]
$quantity = $request->get('quantity');
// [5, 1, 2]
Now I want to submit this arrays into database where I want to pick the purchase_price from product database. I'm not sure how to assign product_id to product_quantity (index 0 to 0, 1 to 1, 2 to 2) and store into database.
Sample data to store into carts:
[1 5 120 ],
[3 1 230 ],
[4 2 340 ],
foreach ($product_id as $product)
{
}
DB::table('carts')->insert(
['product_id' => '',
'quantity' => 0,
'purchase_price' =>
]
);
Just for clarification:
product_id and quantity come from dynamic input box means number of product_id and quantity are same but it could be n times as user wanted. So I store it as arrays.
Now from this array I wanted to store it in database where I want to store with product_id with quantity.
Lets give you some suggetions:
If you have below array - if not then make it array like below:
$dataset = [
0 => [
'product_id' => 1,
'quantity' => 5,
'purchase_price' => 120,
],
1 => [
'product_id' => 3,
'quantity' => 1,
'purchase_price' => 230,
],
2 => [
'product_id' => 4,
'quantity' => 2,
'purchase_price' => 340,
]
];
Now you have to write INSERT query for this:
$result = Cart::insert($dataSet);
if ($result)
return true;
else
return false;
You will get an idea how to do it after seeing above code...good luck
Please check out this sample.
you can parse 2d array and convert it to json to store in the database then decode back:
$product_id = [1,2,3];
// [1, 3, 4]
$quantity = [5,1,2];
// [5, 1, 2]
$output=[120,230,340];
$out=[];
for ($i=0; $i < count($product_id); $i++) {
$out[$i]=[$product_id[$i],$quantity[$i],$output[$i]];
}
dd(json_encode($out));
output:
"[[1,5,120],[2,1,230],[3,2,340]]"
You can use
foreach ($product_id as $key=>$product)
{
//select purchase price from table by using the $product value
$purchase_price = *your select code here*
DB::table('carts')->insert([
'product_id' => $product,
'quantity' => $quantity[$key],
'purchase_price' => $purchase_price
]);
}
Let me know if not works

php str_replace unexpected char replace

I need to change some words to numbers. Example is below-
$status= str_replace(array("canceled","shipped","processing","complete","pending_payment","closed","fraud","holded","payment_review","pending"),array(4,6,2,10,1,12,0,1,1,2),$sale["status"]);
But if unexpected words come from DB ı want to change it to 0.
Is this possible?
You could do something like this :
$statuses = [
"canceled" => 4,
"shipped" => 6,
"processing" => 2,
"complete" => 10,
"pending_payment" => 1,
"closed" => 12,
"fraud" => 0,
"holded" => 1,
"payment_review" => 1,
"pending" => 2,
];
$status = 0;
if (isset($statuses[$sale["status"]])) {
$status = $statuses[$sale["status"]];
}
This way you can easily see which string value maps to which number. Set the default for $status variable to 0. If the status string given, exists in your "statusmap", replace the $status variable.
Try this,
$status_words = array("canceled", "shipped", "processing", "complete", "pending_payment", "closed", "fraud", "holded", "payment_review", "pending");
$status_ints = array(4, 6, 2, 10, 1, 12, 0, 1, 1, 2);
$status = (in_array(trim($sale["status"]), $status_words) ?
str_replace($status_words, $status_ints, trim($sale["status"])) : '');
Give it a try, this should work.

Get max value from each column of a 2-dimensional array

I have an array within an array, for example:
[
[0, 20, 5],
[5, 0, 15],
[5, 10, 0]
]
I need to get the max number in each column.
The max of [0 , 5 , 5] is 5, so that goes into the result array.
The max of [20, 0, 10] is 20, so that goes into the result array.
The max of [5, 15, 0] is 15, so that goes into the result array.
The final result array must contain [5, 20, 15].
First, the array has to be transposed (flip the rows and columns):
function array_transpose($arr) {
$map_args = array_merge(array(NULL), $arr);
return call_user_func_array('array_map', $map_args);
}
(taken from Is there better way to transpose a PHP 2D array? - read that question for an explanation of how it works)
Then, you can map the max function on the new array:
$maxes = array_map('max', array_transpose($arr));
Example: http://codepad.org/3gPExrhO
Output [I think this is what you meant instead of (5, 15, 20) because you said index 1 should be max of (20, 0, 10)]:
Array
(
[0] => 5
[1] => 20
[2] => 15
)
Without the splat operator, array_map() with max() will return the max value for each row. ([20, 15, 10])
With the splat operator to transpose the data structure, the max value for each column is returned.
Code: (Demo)
$array = [
[0, 20, 5],
[5, 0, 15],
[5, 10, 0]
];
var_export(
array_map('max', ...$array)
);
Output:
array (
0 => 5,
1 => 20,
2 => 15,
)

Categories