How to store different single array to database? - php

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

Related

array filter of PDO result

I get PDO rows array which contains the result:
parent_id , item_id
NULL 2
NULL 3
1 5
1 8
I want a new array where parent_id is not NULl
Means
new arr=[5,8]
You need to set new array from exits or to duplicate request with IS NULL condition. With array method, your code will show like this:
$arr = [
[
'parent_id' => null,
'item_id' => 2,
],
[
'parent_id' => null,
'item_id' => 4
],
[
'parent_id' => 2,
'item_id' => 20,
],
];
$new_arr = array_filter($arr,function ($item) {
return !$item['parent_id'];
});
print_r($new_arr);

Keep array rows where a column value is found in a second flat array

** I have edited this to show how I got my code to work using array_search
I have an array, $arr1 with 5 columns as such:
key id name style age whim
0 14 bob big 33 no
1 72 jill big 22 yes
2 39 sue yes 111 yes
3 994 lucy small 23 no
4 15 sis med 24 no
5 16 maj med 87 yes
6 879 Ike larg 56 no
7 286 Jed big 23 yes
This array is in a cache, not a database.
I then have a second array with a list of id values -
$arr2 = array(0=>14, 1=>72, 2=>8790)
How do I filter $arr1 so it returns only the rows with the id values in $arr2?
I got my code to work as follows:
$arr1 = new CachedStuff(); // get cache
$resultingArray = []; // create an empty array to hold rows
$filter_function = function ($row) use ($arr2) {
return (array_search($row['id'], $arr2));
};
$resultingArrayIDs = $arr1->GetIds($filter_function, $resultingArray);
This gives me two outputs: $resultingArray & $resultingArrayIDs both of which represent the intersection of the $arr1 and $arr2.
This whole task can be accomplished with just one slick, native function call -- array_uintersect().
Because the two compared parameters in the custom callback may come either input array, try to access from the id column and if there isn't one declered, then fallback to the parameter's value.
Under the hood, this function performs sorting while evaluating as a means to improve execution time / processing speed. I expect this approach to outperform iterated calls of in_array() purely from a point of minimized function calls.
Code: (Demo)
var_export(
array_uintersect(
$arr1,
$arr2,
fn($a, $b) =>
($a['id'] ?? $a)
<=>
($b['id'] ?? $b)
)
);
Something like this should do it, provided I've understood your question and data structure correctly:
$dataArray = [
[ 'key' => 0, 'id' => 14 , 'name' => 'bob' , 'style' => 'big' , 'age' => 33 , 'whim' => 'no' ],
[ 'key' => 1, 'id' => 72 , 'name' => 'jill' , 'style' => 'big' , 'age' => 22 , 'whim' => 'yes' ],
[ 'key' => 2, 'id' => 39 , 'name' => 'sue' , 'style' => 'yes' , 'age' => 111 , 'whim' => 'yes' ],
[ 'key' => 3, 'id' => 994 , 'name' => 'lucy' , 'style' => 'small' , 'age' => 23 , 'whim' => 'no' ],
[ 'key' => 4, 'id' => 15 , 'name' => 'sis' , 'style' => 'med' , 'age' => 24 , 'whim' => 'no' ],
[ 'key' => 5, 'id' => 16 , 'name' => 'maj' , 'style' => 'med' , 'age' => 87 , 'whim' => 'yes' ],
[ 'key' => 6, 'id' => 879 , 'name' => 'Ike' , 'style' => 'larg' , 'age' => 56 , 'whim' => 'no' ],
[ 'key' => 7, 'id' => 286 , 'name' => 'Jed' , 'style' => 'big' , 'age' => 23 , 'whim' => 'yes' ]
];
$filterArray = [14, 72, 879];
$resultArray = array_filter( $dataArray, function( $row ) use ( $filterArray ) {
return in_array( $row[ 'id' ], $filterArray );
} );
View this example on eval.in
However, your question appears to suggest this data might be coming from a database; is that correct? If so, perhaps it's more efficient to pre-filter the results at the database-level. Either by adding a field in the SELECT query, that represents a boolean value whether a row matched your filter ids, or by simply not returning the other rows at all.
One way is with foreach loop with array_search()
$result = [];
foreach ($arr1 as $value) { // Loop thru $arr1
if (array_search($value['id'], $arr2) !== false) { // Check if id is in $arr2
$result[] = $value; // Push to result if true
}
}
// print result
print_r($result);
As #DecentDabbler mentioned - if the data is coming out of a database, using an IN on your WHERE will allow you to retrieve only the relevant data.
Another way to filter is to use array functions
array_column extracts the value of the id column into an array
array_intersect returns the elements which are in both $arr1['id'] and $arr2
array_flip flips the resulting array such that the indices into $arr1 indicate the elements in both $arr1 and $arr2
$arr1 = [ [ 'id' => 14, 'name' => 'bob'],
['id' => 72, 'name' => 'jill'],
['id' => 39, 'name' => 'sue'],
['id' => 994, 'name' => 'lucy'],
['id' => 879, 'name'=> 'large']];
$arr2 = [ 14,72,879 ];
$intersection = array_flip(array_intersect(array_column($arr1,'id'),$arr2));
foreach ($intersection as $i) {
var_dump($arr1[$i]);;
}

Remove duplicate objects from array based on one value, keep lowest of other value in PHP?

Right now I have an array of objects in PHP, and some of them have a duplicate value for "id". I'm trying to remove the duplicates but I want to keep the one with the lowest value for "qty".
I know how you'd normally remove duplicate whole objects from an array, but not only if one value is a duplicate and how to keep the lower of another value.
Example:
[
{
id: 1,
qty: 200
},
{
id: 1,
qty: 190
},
{
id: 2,
qty: 10
},
{
id: 2,
qty: 12
},
{
id: 2,
qty: 10
},
{
id: 3,
qty: 5
},
{
id: 4,
qty: 5
},
{
id: 4,
qty: 2
},
]
What I want to end up with would be..
[
{
id: 4,
qty: 2
},
{
id: 3,
qty: 5
},
{
id: 2,
qty: 10
},
{
id: 1,
qty: 190
}
]
Is this possible?
That looks almost like JSON, so assuming you $array = json_decode($json, true) to an associative array:
array_multisort(array_column($array, 'qty'), SORT_DESC, $array);
$result = array_column($array, null, 'id');
Extract an array of qty and sort that descending, sorting the original by that
Extract from that an array with id as the key
Extracting with array_column() will cause the last id key to overwrite the previous ones. The last one will be the one with the lowest qty since it was sorted DESCending.
If you need to get it back to a JSON object, then just re-index:
$json = json_encode(array_values($result));
AbraCadaver came up with such a good answer, but I worked hard to come up with mine, so I want to share it in case it is useful for someone. If anything, it may provide useful for an expanded or more complex array. I went the route of creating a nested loop. Here is the code:
$newArray = [];
for ($i = 0; $i < count($myArray); $i++)
{
$id_column = array_column($newArray, 'id');
$qty_column = array_column($newArray, 'qty');
if (!in_array($myArray[$i]['id'],$id_column)) {
array_push($newArray, $myArray[$i]);
}
else {
$id_pos = array_search($myArray[$i]['id'],$id_column);
if ($myArray[$i]['qty'] < $qty_column[$id_pos])
{
array_splice($newArray,$id_pos,1,$myArray[$i]);
}
}
}
Basically I create a new empty array. I loop through each element of the original array to see if it's in the new array. If not, I add it, and if it is already in the new array, then I check the new Array to see if the qty for that id is higher, if so, I splice in the current row.
It is not necessary to involve a sorting algorithm -- that would only negatively impact the script performance.
If a row's id is not yet presented in the output array, push it into the output array with a temporary first level key. If the row's id is already in the output array, but has a lesser qty, then overwrite the row in the output array.
This task never needs more than one loop. If you want to remove the temporary first level keys, then call array_values() after looping.
Code: (Demo)
$data = [
['id' => 1, 'qty' => 200],
['id' => 1, 'qty' => 190],
['id' => 2, 'qty' => 10],
['id' => 2, 'qty' => 12],
['id' => 2, 'qty' => 10],
['id' => 3, 'qty' => 5],
['id' => 4, 'qty' => 5],
['id' => 4, 'qty' => 2],
];
$result = [];
foreach ($data as $row) {
if (!isset($result[$row['id']]) || $row['qty'] < $result[$row['id']]['qty']) {
$result[$row['id']] = $row;
}
}
var_export(array_values($result));
Output:
array (
0 =>
array (
'id' => 1,
'qty' => 190,
),
1 =>
array (
'id' => 2,
'qty' => 10,
),
2 =>
array (
'id' => 3,
'qty' => 5,
),
3 =>
array (
'id' => 4,
'qty' => 2,
),
)
Here is one of the possible answers, assuming $your_input contains your data as a string…
Method 1
<?php
$your_input=preg_replace('#\s*\{\s*id\s*:\s*([^,]+?),\s*qty\s*:\s*([^,\}]+?)\s*\}\s*(,)?#','{"id":"$1","qty":"$2"}$3',$your_input);
$your_input=json_decode($your_input,true);
$result=[];
foreach($your_input as $a)
if (!array_key_exists($a['id'],$result) or $a['qty']<$result[$a['id']]['qty'])
{
$result[$a['id']]['id']=$a['id'];
$result[$a['id']]['qty']=$a['qty'];
}
$result=json_encode(array_values($result),JSON_PRETTY_PRINT);
echo '<pre>';
print_r($result);
Method 2
<?php
$your_input=str_replace([' ',':'],['"','":'],$your_input);
$your_input=json_decode($your_input,true);
usort($your_input,function($a,$b){return $a['qty']==$b['qty']?0:($a['qty']>$b['qty']?-1:1);});
foreach($your_input as $b) $result[$b['id']]=['id'=>$b['id'],'qty'=>$b['qty']];
$result=json_encode(array_values($result),JSON_PRETTY_PRINT);
echo '<pre>';
print_r($result);
After Method 1 or Method 2 the $result variable should contains the following data string…
[
{
"id": 1,
"qty": 190
},
{
"id": 2,
"qty": 10
}
]

Adding an array of values to an existing array

I've got a foreach where I create an array out of id's, based on the submitted selected checkboxes from my form (which are `checkbox[$id]. So I end up with:
Where 1, 2 and 3 are the submitted id's from the form. So far so good.
Now I also have an input field amount[$id]in my form. When selecting a checkbox, I can enter an amount for that row and submit the results. I need to add the values of amount to my array if id's. My end result should look like this:
[1 => ['amount' => '10'], 2 => ['amount' => '12'], 3 => ['amount' => '5'] // And so on
I tried merging, and array_push, but I seem to be doing it wrong, since I cannot figure it out. Any pointers?
Something like this should work:
$result = [];
$ids = [1,2,3]; // I suppose it is `$_POST['ids']`
$amounts = [1 => 10, 2 => 11, 3 => 22]; // I suppose it is `$_POST['amount']`
foreach ($ids as $id) {
if (!empty($amounts[$id])) {
$result[$id] = ['amount' => $amounts[$id]];
}
}
Using array_combine as advised in comments can be used only if sizes of arrays are equal. So if you have something like:
$ids = [1,2,4];
$amounts = [1 => 10, 2 => 11, 3 => 0, 4 => 22];
print_r(array_combine($ids, $amounts)); // PHP Warning
And second fact - array_combine won't create values as arrays. So
$ids = [1,2,3];
$amounts = [1 => 10, 2 => 11, 3 => 10];
print_r(array_combine($ids, $amounts)); // no subarrays here

PHP multidimensional array counter

Im trying to make a multidimensional array with two columns. Name and Counter. I can do a single array with all the names. But I dont know how to make it multidimensional and be able to still update the counters. Code i got so far is
if (!in_array($prodname, $da)){
array_push($da, $prodname);
}
and then I can dump it back out with a foreach. How do I make it two dimensional? How can I say alright this exists update the old value? etc.
If you only need name and counter then you should just be able to use a normal array:
$nameCountArray = array();
foreach($names as $name){
if(!array_key_exists($name,$nameCountArray)){
$nameCountArray[$name] = 1;
}else{
$nameCountArray[$name] = $nameCountArray[$name] + 1;
}
}
If you do need multidimensional arrays these are just arrays of arrays and can be accessed as such. A good example of this is using a 2d array to store locations (say on a 3 by 3 grid):
$twoDArray = array(
0 => array(0 => 1,
1 => 4,
2 => 7),
1 => array(0 => 2,
1 => 5,
2 => 8),
2 => array(0 => 3,
1 => 6,
2 => 9)
);
//Grab the item at 1,2
$item = $twoDArray[1][2];//Will give '8'
Supposing you want $da to look like this:
Array(
"name1" => array("score1" => 80, "score2" => 100),
"name2" => array("score1" => 50, "score2" => 60),
"name3" => array("score1" => 90, "score2" => 80),
...
)
Then all you need to do is something like:
function setScore($prodName, $scoreName, $score)
{
global $da;
if (!array_key_exists($prodName, $da)) {
$da[$prodName] = array();
}
$da[$prodName][$scoreName] = $score;
}
setScore("name1", "score1", 80);
setScore("name1", "score2", 100);
setScore("name2", "score1", 50);
...
Unless I'm misunderstanding your question, which is very possible.

Categories