Add array to itself in foreach without duplicating? - php

public function GetOpsPremiums()
{
// Get the Cost Multiplier
$costMulti = $this->GetCostMultiplier();
// Get the Prem Ops
$premOps = $this->GetPremOpsEL();
// Get the Factors
$factors = $this->GetFactors();
// Get the full class array
$classArray = $this->GetClassArray();
foreach ($classArray as $key => $values) {
$classTotalHalved = $values / 1000;
$mainMultiplier = $costMulti * $premOps[$key] * $factors[$key]['premops'];
$premium = $classTotalHalved * $mainMultiplier;
$opsPremiums = array(
$key => round($premium)
);
}
return $opsPremiums;
}
I want $opsPremiums to not just iterate 1 at a time. I need it to iterate and add itself to itself.
I tried
foreach ($opsPremiums as $key2 => $values2) {
$opsPremiums = array(
$key => round($premium)
);
}
Can someone explain to me what I need to do in order to get the $opsPremium to stack itself neatly into a single array?

should be so
foreach ($opsPremiums as $key2 => $values2) {
$opsPremiums[] = array(
$key => round($premium)
);
}

I'm a little unsure of what you mean, but are you trying to return all the results in $opsPremium?
The issue is your setting it as an array on each iteration rather than adding to it.
$opsPremium = array();
foreach ($classArray as $key => $values) {
$classTotalHalved = $values / 1000;
$mainMultiplier = $costMulti * $premOps[$key] * $factors[$key]['premops'];
$premium = $classTotalHalved * $mainMultiplier;
$opsPremiums[] = array(
$key => round($premium)
);
}
return $opsPremiums;
Storing $opsPremium outside the loop and adding to it each time will do that for you.
My apologies if this is not what you were asking.

It seems your very confused with the terminology of how to speak about your problem. I believe what you should have asked is, I want to add some extra items including itself to an array for return. In which case the magic you need is array concatenation. Im a little unsure of what your array requires, but you can append anything to any php array with the [] operator. If you respond with a more detailed question perhaps I can help you further.
Depending on what your are adding to your array, for the program to function you may need to use the array_merge, array_push.

Related

php array returning duplicate values

I am trying to loop through each key but i am facing a problem of same value repeating inside for each loop
Please be noted we should keep on same code structure multiple foreach it's requirement i already posted this question here but didn't get solution instead of solution entire new code as answer imposed on me and nobody is actually taking care of it
Here is example of my current code and result (click here)
here is my code so far
<?php
$data2 = array(
'category_name' => '33287*100*prescription*1,32457*1250*lab*1'
);
$result = array('0' => (object)$data2);
foreach ($result as $key => $category) {
$category_name = explode(',', $category->category_name);
}
$newresults=[];
foreach ($category_name as $key) {
$category->category_name = $key;
$newresults[]=$category;
}
$result=$newresults;
$newresults=[];
$category->items_count = 0;
foreach ($result as $key => $value) {
list($sale_key, $sale_value) = explode('*', $value->category_name);
// $category->items_count += count($sale_value);
$newresults[]=$category;
}
$result=$newresults;
i am getting the wrong results like this
Array
(
[0] => stdClass Object
(
[category_name] => 33287*100*prescription*1
)
[1] => stdClass Object
(
[category_name] => 33287*100*prescription*1
)
)
As noted, because you are reusing variable names, and also using them when their scope might not be correct or accepted, you are causing some confusion.
The code below brings the bottom loop inside of the top loop, because that's where the context really lives. Creating a temporary loop only adds to the potential confusion. If that doesn't work with the additional logic, more changes will be needed. I also changed a bunch of the variable names to hopefully make things more obvious. See the comments in the code for more details.
$reporting_data = array(
'category_name' => '33287*100*prescription*1,32457*1250*lab*1,32459*1500*lab*1,32460*400*lab*1,32461*600*lab*1,32468*950*lab*1,32470*950*lab*1,33291*2500*lab*1,33292*2500*lab*1,47516*2000*lab*1,49209*0*lab*1,56835*2400*lab*1,56836*2400*lab*1',
'patient' => '28370',
'date' => 1643030497,
'ref' => '371',
);
// Create array of objects
$reporting_data_as_objects[] = (object)$reporting_data;
$results = [];
foreach ($reporting_data_as_objects as &$obj) {
// Setup base data that is shared across all items
$obj->reception_data_sum = 0;
$obj->references_data_sum = 0;
$obj->actual_price = 0;
$category_names = explode(',', $obj->category_name);
// Loop over the comma-delimited parts of category_name
foreach ($category_names as $category_name) {
// Clone our template object
$tmp = clone $obj;
// The second item of the asterisk-delimted field is the price
// We used $_ to indicate that we aren't interested in the first item.
list($_, $sale_value) = explode('*', $category_name);
// Set object-specific fields on our clone
$tmp->category_name = $category_name;
$tmp->actual_price = (int)$sale_value;
// Add the clone to the array
$results[] = $tmp;
}
}
// Always unset by-ref variables of a foreach
unset($obj);
print_r($results);
Demo here: https://3v4l.org/95KAQ

Multidimensional arrays in PHP - how to add values using foreach

I have a multidimensional array defined as follows
$SquadList = array('name', 'position', 'dob', 'nation', 'games', 'goals', 'assists');
I'm looping through several foreach loops and storing data from JSON
foreach ($season as $key => $squad){
$SquadList[0] = $squad['full_name'];
$SquadList[1] = $squad['position'];
$SquadList[2] = gmdate("d-m-y", $birthday);
$SquadList[3] = $squad['nationality'];
$SquadList[4] = $squad['appearances_overall'];
$SquadList[5] = $squad['goals_overall'];
$SquadList[6] = $squad['assists_overall']; }
foreach ($season1 as $key => $squad){
$SquadList[0] = $squad['full_name'];
$SquadList[1] = $squad['position'];
$SquadList[2] = gmdate("d-m-y", $birthday);
$SquadList[3] = $squad['nationality'];
$SquadList[4] = $squad['appearances_overall'];
$SquadList[5] = $squad['goals_overall'];
$SquadList[6] = $squad['assists_overall'];
The code is messy. The output is only 2 elements when it should be 30+
I've tried array_push as follows
array_push($SquadList['name'], $squad['full_name'];
i'm not sure if i get the question correctly, but i imagine you want it to be structured something like this:
$SquadList = []; // define it as an array
$ctr = 0; // define a counter that would be used in the two iterations
foreach ($season as $key => $squad){
$SquadList[$ctr][0] = $squad['full_name'];
$SquadList[$ctr][1] = $squad['position'];
$SquadList[$ctr][2] = gmdate("d-m-y", $birthday);
$SquadList[$ctr][3] = $squad['nationality'];
$SquadList[$ctr][4] = $squad['appearances_overall'];
$SquadList[$ctr][5] = $squad['goals_overall'];
$SquadList[$ctr][6] = $squad['assists_overall'];
$ctr++; // increase counter
}
foreach ($season1 as $key => $squad){
$SquadList[$ctr][0] = $squad['full_name'];
$SquadList[$ctr][1] = $squad['position'];
$SquadList[$ctr][2] = gmdate("d-m-y", $birthday);
$SquadList[$ctr][3] = $squad['nationality'];
$SquadList[$ctr][4] = $squad['appearances_overall'];
$SquadList[$ctr][5] = $squad['goals_overall'];
$SquadList[$ctr][6] = $squad['assists_overall'];
$ctr++; // increase counter
}
The reason you had two results is because you got the last squad for each season. This happened because each time a season iterated, it overwrote the previous squad.
To solve this problem, $SquadList must be an array. But you have to assign all its members at once, otherwise the array will increment every time you add a member.
Populating an array of arrays
foreach ($season as $key => $squad) {
$squadList[] = [
$squad['full_name'],
$squad['position'],
gmdate("d-m-y", $squad['birthday']),
$squad['nationality'],
$squad['appearances_overall'],
$squad['goals_overall'],
$squad['assists_overall']
];
}
Note a couple of changes I made:
I removed the capitalization on $squadList because convention has starting with a capital indicating an object, not a plain old variable
$birthday was undefined, so I made an educated guess
Cleaning up the code
You mentioned that “the code is messy”. That is a very healthy observation to make.
What you are noticing is the result of two things:
Your code is repeating itself (a violation of DRY - Don’t Repeat Yourself)
Need to follow convention of PSR-12
So let’s get rid of the code duplication
Refactoring
When you start repeating yourself, that’s a signal to pull things into a function
function buildSquad(array $season)
{
foreach ($season as $key => $squad) {
$squadList[] = [
$squad['full_name'],
$squad['position'],
gmdate("d-m-y", $squad['birthday']),
$squad['nationality'],
$squad['appearances_overall'],
$squad['goals_overall'],
$squad['assists_overall']
];
}
return $squadList;
}
$squadList = [];
// if you just want to lump them all together
$squadList[] = buildSquad($season);
$squadList[] = buildSquad($season2);
// etc

PHP assoiative Array with almost Similar Keys

I have an associative array
array(
'item_name1' => 'PCC',
'item_name2' => 'ext',
'item_number1' => '060716113223-13555',
'item_number2' => '49101220160607-25222)',
)
What i Want to do is catch all the array keys where the key name has similarities
for example
i want to echo out item_name (it should get both item_name1 & item_name2) but i require it in a loop (foreach/for) so that i can send within the loop the details to my database for each set of values
Thanks For the help
Use the funtion array_keys
$allKeys = array_keys($yourArray);
$amountKeys = count($allKeys);
Unless you do not provide more code this will give you all the keys of $yourArray
Reference - array_keys
To get all the similar keys you can use this function similar-text()
Since I do not know how "similar" a key can be I would suggest you to test out different values and find a degree that matches your expectations.
Your data model seems to use numeric suffixes as a replacement for arrays so I'll assume that key name has similarities is an overestimated problem statement and you merely want to fix that.
The obvious tool is regular expressions:
$original_data = array(
'item_name1' => 'PCC',
'item_name2' => 'ext',
'item_number1' => '060716113223-13555',
'item_number2' => '49101220160607-25222)',
);
$redacted_data = array();
foreach ($original_data as $key => $row) {
if (preg_match('/^(.+)(\d+)$/u', $key, $matches)) {
$redacted_data[$matches[1]][$matches[2]] = $row;
} else {
$redacted_data[$key][] = $row;
}
}
var_dump($redacted_data);
It should be easy to tweak for your exact needs.
I can't figure out what the i require it in a loop (foreach/for) requirement means but you can loop the resulting array as any other array:
foreach ($redacted_data as $k => $v) {
foreach ($v as $kk => $vv) {
printf("(%s,%s) = %s\n", $k, $kk, $vv);
}
}
<?php
$items=[];
$itemsNumbers=[];
foreach($itemarr as $key=> $val)
{
$itempos = strpos("item_name", $key);
if ($pos !== false)
$items[]=$val;
$numberpos = strpos("item_number", $key);
if ($numberpos !== false)
$itemsNumbers[]=$val;
}
?>
Note: here $itemarr is your input array
$items you will get list of item names and $itemsNumbers you will get list of itemsNumbers

php - Find array for which a key have a given value

I have an array of dictionnaries like:
$arr = array(
array(
'id' => '1',
'name' => 'machin',
),
array(
'id' => '2',
'name' => 'chouette',
),
);
How can I find the name of the array containing the id 2 (chouette) ?
Am I forced to reindex the array ?
Thank you all, aparently I'm forced to loop through the array (what I wanted to avoid), I thought that it were some lookup fonctions like Python. So I think I'll reindex with id.
Just find the index of array that contains the id you want to find.
SO has enough questions and answers on this topic available.
Assuming you have a big array with lots of data in your real application, it might be too slow (for your taste). In this case, you indeed need to modify the structure of your arrays, so you can look it up faster, e.g. by using the id as an index for the name (if you are only interested in the name).
As a for loop would be the best way to do this, I would suggest changing you array so that the id is the arrays index. For example:
$arr = array(
1 => 'machin',
2 => 'chouette',
);
This way you could just get the name for calling $arr[2]. No looping and keeping your program running in linear time.
$name;
foreach ($arr as $value){
if ( $value['id'] == 2 ){
$name = $value['name'];
break;
}
}
I would say that it might be very helpful to reindex the information. If the ID is unique try something like this:
$newarr = array();
for($i = 0;$i < count($arr);$i++){ $newarr[$arr[$i]['id']] = $arr[$i]['name']; }
The result would be:
$newarr = array('1'=>'machin','2'=>'chouette');
Then you can go trough the array with "foreach" like this:
foreach($newarr as $key => $value){
if($value == "machin"){
return $key;
}
}
But of course the same would work with your old array:
foreach($arr as $item){
if($item['name'] == "machin"){
return $item['id'];
}
}
It depends on what you are planning to do with the array ;-)
array_key_exist() is the function to check for keys. foreach will help you get down in the multidimensional array. This function will help you get the name element of an array and let you specify a different id value.
function findKey($bigArray, $idxVal) {
foreach($bigArray as $array) {
if(array_key_exists('id', $array) && $array['id'] == $idxVal) {
return $array['name'];
}
}
return false;
}
//Supply your array for $arr
print(findKey($arr, '2')); //"chouette"
It's a bit crude, but this would get you the name...
$name = false;
foreach($arr as $v) {
if($v['id'] == '2') {
$name = $v['name'];
break;
}
}
echo $name;
So no, you are not forced to reindex the array, but it would make things easier.

Split a string to form multidimensional array keys?

I'm creating JSON encoded data from PHP arrays that can be two or three levels deep, that look something like this:
[grandParent] => Array (
[parent] => Array (
[child] => myValue
)
)
The method I have, which is simply to create the nested array manually in the code requires me to use my 'setOption' function (which handles the encoding later) by typing out some horrible nested arrays, however:
$option = setOption("grandParent",array("parent"=>array("child"=>"myValue")));
I wanted to be able to get the same result by using similar notation to javascript in this instance, because I'm going to be setting many options in many pages and the above just isn't very readable, especially when the nested arrays contain multiple keys - whereas being able to do this would make much more sense:
$option = setOption("grandParent.parent.child","myValue");
Can anyone suggest a way to be able to create the multidimensional array by splitting the string on the '.' so that I can json_encode() it into a nested object?
(the setOption function purpose is to collect all of the options together into one large, nested PHP array before encoding them all in one go later, so that's where the solution would go)
EDIT: I realise I could do this in the code:
$options['grandparent']['parent']['child'] = "myValue1";
$options['grandparent']['parent']['child2'] = "myValue2";
$options['grandparent']['parent']['child3'] = "myValue3";
Which may be simpler; but a suggestion would still rock (as i'm using it as part of a wider object, so its $obj->setOption(key,value);
This ought to populate the sub-arrays for you if they haven't already been created and set keys accordingly (codepad here):
function set_opt(&$array_ptr, $key, $value) {
$keys = explode('.', $key);
// extract the last key
$last_key = array_pop($keys);
// walk/build the array to the specified key
while ($arr_key = array_shift($keys)) {
if (!array_key_exists($arr_key, $array_ptr)) {
$array_ptr[$arr_key] = array();
}
$array_ptr = &$array_ptr[$arr_key];
}
// set the final key
$array_ptr[$last_key] = $value;
}
Call it like so:
$opt_array = array();
$key = 'grandParent.parent.child';
set_opt($opt_array, $key, 'foobar');
print_r($opt_array);
In keeping with your edits, you'll probably want to adapt this to use an array within your class...but hopefully this provides a place to start!
What about $option = setOption("grandParent", { parent:{ child:"myValue" } });?
Doing $options['grandparent']['parent']['child'] will produce an error if $options['grandparent']['parent'] was not set before.
The OO version of the accepted answer (http://codepad.org/t7KdNMwV)
$object = new myClass();
$object->setOption("mySetting.mySettingsChild.mySettingsGrandChild","foobar");
echo "<pre>".print_r($object->options,true)."</pre>";
class myClass {
function __construct() {
$this->setOption("grandparent.parent.child","someDefault");
}
function _setOption(&$array_ptr, $key, $value) {
$keys = explode('.', $key);
$last_key = array_pop($keys);
while ($arr_key = array_shift($keys)) {
if (!array_key_exists($arr_key, $array_ptr)) {
$array_ptr[$arr_key] = array();
}
$array_ptr = &$array_ptr[$arr_key];
}
$array_ptr[$last_key] = $value;
}
function setOption($key,$value) {
if (!isset($this->options)) {
$this->options = array();
}
$this->_setOption($this->options, $key, $value);
return true;
}
}
#rjz solution helped me out, tho i needed to create a array from set of keys stored in array but when it came to numerical indexes, it didnt work. For those who need to create a nested array from set of array indexes stores in array as here:
$keys = array(
'variable_data',
'0',
'var_type'
);
You'll find the solution here: Php array from set of keys

Categories