Query regarding associative arrays PHP - php

I have a question about associative arrays in php.
I have following array in which there are two items named 4 and 2 respectively.
$items = array(4,2);
Now i want to associate each item's quantity to it which can be done as follows:
$items['4']=23;
$items['2']=0;
which means that there are 23, 'item 4s' and no 'item 2'.
But I sometimes don't know in advance what is there in the $items so i want to associate quantity on basis of location. I wanted to do something like associate 23 to whatever is there on the zero location of the item array:
$items['items[0]']=23;
This of course did not work because its not the right way to extract whatever is placed on the zero location of items. Can anyone please tell me how do i do that?

You are confusing in the use of item and items. I imagine you have both an item array and an items array, else things can easily get hairy.
Anyhow, you just refer to it as a variable, not as a string:
$items[$item[0]] = 23;

Let me get this straight. So you start with an array that looks like this:
$items = array( 0 => 4, 1 => 2 )
And you want to end up with an array that looks like this: ?!
$items = array( 0 => 4, 1 => 2, 2 => 0, 4 => 23 )

I think you should use your array as a kind of "map". The item number is your key, and the quantity your value.
By calling
$items = array(4,2);
you create
$items[0] = 4;
$items[1] = 2;
but you want to use the 4 and 2 as a key in your array. So you should instead use
$items = array( 4 => false, 2 => false );
where false stands for an item that has not yet a quantity associated (could also be e.g. -1).
This creates
$items[2] = false;
$items[4] = false;
When using false, you can check for not assigned values by calling
if ($items[4] === false) {
echo "No quantity set!";
}
And now the second step.. if you want to assign the item #4 a quantity of 23, just call
$items[4] = 23;
So I don't think you will want to rely on the order inside your array..

Related

Restructure 2d array so that column values become row values (transpose but preserve first level keys)

The situation is as follows. I have a parent array which looks like the following:
$parent = [
1 => ['test1', 'test2'],
2 => ['test1_1', 'test2_2'],
];
I would like to group the data by column.
Desired result:
[
1 => ['test1', 'test1_1'],
2 => ['test2', 'test2_2'],
]
1 parent array called parent contains 2 arrays inside. I want to combine these two so that they have the same values as stated above. So this would mean that the arrays should be combined based on index number.
Since I do not make use of string keys, how would I accomplish this? I believe that there is no build in function available for this situation.
I would imagine that I could start beginning to create a new array and use a for loop through the parent array.
I tried the array-combine function however, this is NOT displaying the results I want.
[
1 => ['test1' => 'test1_1', 'test2' => 'test2_2'
]
If you need to preserve those first level keys, you can re-apply them after tranposing.
Code: (Demo)
var_export(
array_combine(array_keys($parent), array_map(null, ...$parent))
);
Otherwise, you can just transpose and accept the re-indexed first level keys. Honestly, I can't see any good reason to preserve the first level keys because by transposing, you remove the initial association between first level keys and the row values.
Code: (Demo)
var_export(
array_map(null, ...$parent)
);
If these techniques do not suit your actual project data, then we will need a more realistic sample array to be provided in your question body.
Loop over the keys of the top-level array. Then use the current index of the iteration to get the corresponding columns of the nested arrays.
$result = [];
foreach (array_keys($parent) as $i => $k) {
$result[$k] = array_column($parent, $i);
}
DEMO
This assumes the number of rows is the same as the number of columns. It's not clear what you expect the result to be if that's not true.

Generate a PHP array with 100 tickets and a random number to compare

I am new to symfony and I am trying to make a function that generates a random number and then I want to check this random number in an array of prices. Let's say there are 100 tickets so 100 items in the array. 50 of them are a price "foo" 30 "bar" and 0 "win nothing".
My goals is to populate this array at random so it should look like this:
array(
1=>foo,
2=>foo,
3=>bar,
4=>nothing,
...
)
EDIT
here is what i've tried but doesn't seem to be working. The array is being filled with only the last fill
$prices = array_fill(0, 99, '10');
$prices = array_fill(100, 139, '100');
$prices = array_fill(139, 149, '200');
$prices = array_fill(149, 150, 'reis');
($prices);
I have no idea how to populate my array at random and could use all the help in the world
Any help would be realy awesome!
Thanks in advance!
Your problem can be broken up into two simple parts. First, you need to create an array with an arbitrary number of values, which you could do with a function like this, as per your requirements described above.
function createTickets(Array $items, $totalItems) {
$arr = [];
// populate each item with $quantity
foreach($items as $item => $quantity) {
$arr = array_merge($arr, array_fill(0, $quantity, $item));
}
// fill in the rest with 'nothhing'
$arr = array_merge($arr, array_fill(0, $totalItems - array_sum($items), 'nothing'));
// return the final result
return $arr;
}
So, to create an array of 100 items, with 50 foo and 30 bar, and the rest are nothing, you would do something like this.
$tickets = createTickets(['foo' => 50, 'bar' => 30], 100);
Second, you need to select items at random from the array you created.
The actual order of the elements in the array doesn't matter. You can use something like shuffle to randomize the order of elements in the array, but that's not necessary, because you can always select items from the array at random using array_rand, for example.
// Randomly select an item from the array
$someItem = $tickets[array_rand($tickets)];
Becuase you already know how many items you're creating in the array, you can always supply the amount of random items to extract to array_rand.
// Select 10 items at random
foreach(array_rand($tickets, 10) as $key) {
echo $tickets[$key], "\n"; // do something with item here
}
If you prefer to just shuffle the array because you intend to consume the entire array at random you could just do that instead.
shuffle($tickets);
foreach($tickets as $ticket) {
// now each item is at random
}

Update value in session array php

I have question about the SESSION array.
I just add item and qty in different session. I use code like this :
$_SESSION['idproduct'] = $id.",";
$_SESSION['qtyproduct'] = $qty.",";
I have write the condition so the value of session will be like this if we add 3 item :
$_session['idproduct'] = 1,4,6,
$_session['qtyproduct'] = 3,4,5,
my question is how to update quantity if i have get the id ?
Store them as arrays, that way you can access the quantity using the ID as a key:
$_SESSION['quantity'][$id] = $quantity;
So instead of storing your ID and Quantity in two separate strings, you have them in one array, with the ID as the key. Converting your example above your array will look like this:
array(
1 => 3
4 => 4
6 => 5
);
Then if you wanted to add / adjust anything you just set $id and $quantity to the appropriate values and use the line above.
You could use explode function and push another item into the array
$items = explode($_SESSION['idproduct']);
$items[] = $your_new_value;
print_r($items); // this will you the values inside the array.
$_SESSION['idproduct'] = implode(',', $items);
The best way to achieve it is to store quantity as a value with product ID as a key, so if you have:
idproduct = 1,4,6,
qtyproduct = 3,4,5,
Store it as:
$_SESSION['qtyproduct'] = array(
1 => 3,
4 => 4,
6 => 5,
);
Right now if you have a product id:
$id = 4;
You can access quantity with:
$quantity = $_SESSION['qtyproduct'][$id];
and modify it with:
$_SESSION['qtyproduct'][$id] = 7;

Fast method for Looping through Array to match a common ID in a second array

I'm trying to systematically loop through 2 arrays, and match their values for some quick processing. Let me set up my specific situation:
Array 1
productID,
companyID,
name,
price
Array 2
companyID,
name,
rebate1,
rebate2
I want to loop through Array 1, and when the companyID matches an ID inside of Array 2, I will do some quick math based on the rebate1, rebate2 values for that companyID.
Right now I am looping through Array 1, and then on EACH item in Array 1 I loop through the entire Array 2 to see if the companyID exists. I know this can't be the fastest/cleanest solution...
EDIT
The key values for Array 1 look like:
$array1[0]['productID']
$array1[0]['companyID'] (etc...)
$array1[1]['productID']
$array1[1]['companyID'] (etc...)
The key values for Array 2 look like:
$array2[0]['companyID']
$array2[0]['rebate1'] (etc...)
$array2[1]['companyID']
$array2[1]['rebate1'] (etc...)
Use the companyId as key for Array 2, i.e., make sure that
$Array2[$Array1[$i]['companyID']]['companyID'] == $Array1[$i]['companyID']
This gives you constant time lookup of companies in Array 2 based on companyID and you can do your calculation with
$Array2[$Array1[$i]['companyID']]['rebate1']`
and
$Array2[$Array1[$i]['companyID']]['rebate2']`
Example:
foreach ($Array1 as $value) {
if (isset($Array2[$value['companyID']])) {
//TODO: use $Array2[$value['companyID']] for calculation
} else {
// TODO: handle case companyID not in $Array2
}
}
What approximate sizes do you expect for each of your arrays?
While as you say, your method isn't certainly the fastest (looks like 0(n²)), below 10'000 elements in each array I doubt you can see any significant speed difference.
If you have 150'000 in array1 and 200'000 in array2, that's a whole other story and you'll have to look for an algorithm that is rather 0(log n).
Edit:
As mentioned above, let's just make your array associative if you can:
Instead of:
Array2 = array(
0 => array(
'Company_id' => 'Hello',
'rebate_1' => '50%',
)
);
Make it:
Array2 = array(
'Hello' => array(
'rebate_1' => '50%',
)
);
And then use:
if (isset(array2[$company_id]))
{
// do your stuff
}
If you can't modify Array2's structure where it's coming from, you should transform it on the fly in your search function's scope, so that it looks like above, and then use the transformed array. Transforming Array2 into an associative one shouldn't take too long, for the number of elements you say you have.
The easiest way I can think of is to use the companyID as the key for Array 2:
$companies[$companyID]=array($name,$rebate1,$rebate2)
and then you just reference it directly looping Array 1
$products[$x]=array($productID,$companyID,$name,$price);
...
$newprice1=$products[$x][3]/$companies[$products[$x][1]][1];
$newprice2=$products[$x][3]/$companies[$products[$x][1]][2];
My answer is slightly different from the first one, mind the arrays...
You can create a new array indexed by the company id as follows:
$cid = array_map(function($a) {return $a['companyID'];}, $array2);
$new2 = array_combine($cid, $array2);
With that, you can loop through the first array and access the data:
foreach ($array1 as $key => $value){
$rebate1 = $new2[$value['companyID']]['rebate1'];
$rebate2 = $new2[$value['companyID']]['rebate2'];
}

PHP: Session 2-Dimensional Array - Track Viewed Products

I'm trying to create an array to display the last 5 products a customer has viewed.
The array is a 2 dimensional array like below...
$RView= array(
array( ID => "1001", RefCode => "Ref_01", Name => "Name_01" ),
...
array( ID => "1005", RefCode => "Ref_05", Name => "Name_05" )
);
The array values are retrieved from the products recordset and is designed to function as follows when a customer visits a product page.
Page will check if a Session Array exists
If yes, an array variable is created from existing Session
If no, a new array is created.
Array will add the new product details.
Array will count if there are more than 5 existing products in the array.
If yes, it will remove the oldest.
If no, moves to next step.
A Session is created/updated from the revised Array.
My current effort is attached below...
Many thanks for any help.
<?php
session_start()
// Get or Create Array
IF (isset($_SESSION['sessRView'])) {
$RView = ($_SESSION['sessRView']); }
ELSE {
$RView = array(array());
}
// Append currently viewed Product to Array
array(array_unshift($RView, $row_rsPrd['PrdID'], $row_rsPrd['RefCode'], $row_rsPrd['Name']));
// Check if more than 5 products exist in Array, if so delete.
IF (sizeof($RView) > 5) {
array(array_pop($RView)); }
// Update Session for next page
$_SESSION['sessRView'] = $RView;
// Display Array
for ($row = 0; $row < 5; $row++)
{
echo "<ul>";
echo "<li><a href='?PrdID=".$RView[$row]["PrdID"]."'>".$RView[$row]["RefCode"]."</a> : ".$RView[$row]["Name"]."</li>";
echo "</ul>";
}
?>
It's more or less right - just 2 lines need to be changed.
There's no need for the extra array() around array_unshift and array_pop.
When you use array_unshift you're pushing an array of items (not the id/codes individually) - I think you mean array_unshift($RView, array($prodid,$name,...))
What if $RView doesn't have 5 elements? In that case you're accessing undefined array indices (which may or may not show an error). Change it to a foreach loop: e.g.
foreach ($Rview as $prod) echo $prod['Name']...
It should work after you make these changes. You might want to clean up the coding style a bit, though :)
EDIT: Oh, I see, when you're referencing the array in the for loop it doesn't know that the array has "ProdID" and "Name" indices. When you make an array you have to define the indexes using the => operator.
Add indexes to the array when you array_unshift:
array_unshift($RView, array("ProdID" => $row_rsProd["ProdID"], "Name"...))
If row_rsProd isn't too big, you can just tack the entire row_rsprod onto $RView.
so change array_unshift(...) to just $RView[] = $row_rsProd
This way the indexes are preserved.
Alternatively you can change the indicies in the for loop to match. Right now the array you unshift onto $RView is 0-based - $RView[0][0] is the product ID for the first product, etc.
So you can change the stuff in the foreach loop to
echo "<li>..." $prod[0] $prod[1] $prod[2]
Hope that helps!

Categories