Add values in second array depending upon the values in first array - php

Here's the situation:
Suppose I have first Array as:
Array(
[0] => Person1
[1] => Person1
[2] => Person2
)
And second array as:
Array(
[0] => 100.00
[1] => 150.25
[2] => 157.15
)
How do I add values (100.00 + 150.25) of second Array and merge them (250.25) so that they belong to Person1 in the first array.
Desired Output:
Array(
[0] => 250.25 // for Person1 in the first Array after adding
[1] => 157.15 // for Person2 in the first Array
)
Any help is highly appreciated. Thank You.
P.S.: All the values are coming from the database.
EDIT 1:
Here's what I have tried, but this outputs the second array as it is:
$sums = array();
$sums = array_fill_keys(array_keys($affiCode + $affiCommAmount), 0);
array_walk($sums, function (&$value, $key, $arrs) {
$value = #($arrs[0][$key] + $arrs[1][$key]);
}, array($affiCode, $affiCommAmount)
);

The arrays are the same size, so you can use a for loop to process them simultaneously:
for($i = 0; $i<count($personArray); $i++)
Within the loop, construct a new array keyed to the values from the first array. If the key does not yet exist, initialize it:
if (!isset($newArray[$personArray[$i]])) {
$newArray[$personArray[$i]] = 0.0;
}
then add the new value to the selected array key:
$newArray[$personArray[$i]] += $valueArray[$i]
When the loop ends, $newArray will look like:
Array(
['Person1'] => 250.25
['Person2'] => 157.15
)
If you want to replace the 'Person1' and 'Person2' keys with numerical indexes, use array_values():
$numericallyIndexedArray = array_values($newArray);
The final code looks like:
$newArray = [];
for($i = 0; $i<count($personArray); $i++) {
if (!isset($newArray[$personArray[$i]])) {
$newArray[$personArray[$i]] = 0;
}
$newArray[$personArray[$i]] += $valueArray[$i];
}
// Optionally return the new array with numerical indexes:
$numericallyIndexedArray = array_values($newArray);

Get the person from first array by index and add the money:
for($i=0;$i<count(arrayPerson);$i++){
$arrayPerson[$i]->addMoney($arrayMoney[$i])
//Or $arrayPerson[$i]->Money += $arrayMoney[$i]
} //$i defines your index in the array.
sql
Better though to make a join in the SQL and sum the money and group by PersonID.
for example:
SELECT person.* COUNT(Money) FROM Person
LEFT JOIN Money
ON person.ID = Money.PersonID
GROUP BY person.ID

Simple foreach loop:
$people = array('Person1', 'Person1', 'Person2');
$values = array(100.00, 150.25, 157.15);
$output = array();
foreach ($people as $key => $person) {
if (! isset($output[$person])) {
$output[$person] = 0;
}
if (! empty($values[$key])) {
$output[$person] += $values[$key];
}
}
// $output = array(2) { ["Person1"]=> float(250.25) ["Person2"]=> float(157.15) }
If you want to do away with the keys in $output, you can use array_values($output)
Here's an example

Related

PHP calculate array data

I am having trouble to calculate the sum of an array values
my array is
$bar_chart_data =
array(
array(
array("Data1",548.25),
array("Data2",238.75),
array("Data3",95.50),
array("Data4",300.50),
array("Data5",286.80),
array("Data6",148.25)
)
);
I am using this php code to calculate the results but its always gives me 0
$sumArray = array();
foreach ($bar_chart_data as $k=>$subArray) {
foreach ($subArray as $id=>$value) {
$sumArray[$id]+=$value;
}
}
print_r($sumArray);
Your $id is different in all iteration.
You have to use $sumArray[$k]+=$value[1];.
You also have to init $sumArray[$k] to 0 between your two foreach.
I believe you have an array containing a sub-array and you want to get the sum of all the values in each of the sub-arrays.
I suggest you use an associative sub-array to make the task easier.
$bar_chart_data = array(
array(
"Data1" => 548.25,
"Data2" => 238.75,
"Data3" => 95.50,
"Data4" => 300.50,
"Data5" => 286.80,
"Data6" => 148.25
),
array(
)
);
$sumArray = array(); // Create an empty array to store the sum of each sub-array
foreach ($bar_chart_data as $subArray) {
$sum = 0; // Initialize sum as zero
foreach ($subArray as $key=>$value) {
$sum += $value;
}
$sumArray[] = $sum; // Append each sum to the array
}
print_r($sumArray); // Print the array containing the sums.
You only need one loop, then extract the values at index 1 and sum them:
foreach($bar_chart_data as $values) {
$sumArray[] = array_sum(array_column($values, 1));
}
You can add the $k => $values back and use $sumArray[$k] if needed, but the way your array is shown it will work without it.

Group subarrays by one column, make comma-separated values from other column within groups

I have a array that looks like this:
$array = [
["444", "0081"],
["449", "0081"],
["451", "0081"],
["455", "2100"],
["469", "2100"]
];
I need to group as a new array that looks like:
array (
0 =>
array (
0 => '444,449,451',
1 => '0081',
),
1 =>
array (
0 => '455,469',
1 => '2100',
),
)
I'd tried many scripts, but with no success.
function _group_by($array, $key) {
$return = array();
foreach($array as $val) {
$return[$val[$key]][] = $val;
}
return $return;
}
$newArray = _group_by($array, 1); // (NO SUCCESS)
There should be more elegant solutions, but simplest one I can think of would be this.
// The data you have pasted in the question
$data = [];
$groups = [];
// Go through the entire array $data
foreach($data as $item){
// If the key doesn't exist in the new array yet, add it
if(!array_key_exists($item[1], $groups)){
$groups[$item[1]] = [];
}
// Add the value to the array
$groups[$item[1]][] = $item[0];
}
// Create an array for the data with the structure you requested
$structured = [];
foreach($groups as $group => $values){
// With the array built in the last loop, implode it with a comma
// Also add the 'key' from the last array to it ($group)
$structured[] = [implode(',', $values), $group];
}
I haven't tested this but something similar should do the trick. This simply goes through the given array and collects all entries in a structurized manner (so $groups variable will contain an array entry for each group sharing a key, and the key will correspond to the 2nd item in each item within the given array). From there it's just about restructuring it to get the format you have requested.
http://php.net/manual/en/control-structures.foreach.php
Writing two loops is too much effort for this task. Use isset() with temporary keys applied to your output array as you iterate. When finished grouping the data, reindex the output with array_values().
Code (Demo)
$array = [
["444", "0081"],
["449", "0081"],
["451", "0081"],
["455", "2100"],
["469", "2100"]
];
foreach ($array as $row) {
if (!isset($result[$row[1]])) {
$result[$row[1]] = $row; // first occurrence of group, save whole row
} else {
$result[$row[1]][0] .= ',' . $row[0]; // not first occurrence, concat first element in group
}
}
var_export(array_values($result));
Or avoid the temporary associative arrays in the result array by using an array of references. (Demo)
$result = [];
foreach ($array as $row) {
if (!isset($ref[$row[1]])) {
$ref[$row[1]] = $row;
$result[] = &$ref[$row[1]];
} else {
$ref[$row[1]][0] .= ',' . $row[0];
}
}
var_export($result);
Or use array_reduce() to enjoy a functional-style technique. (Demo)
var_export(
array_values(
array_reduce(
$array,
function($result, $row) {
if (!isset($result[$row[1]])) {
$result[$row[1]] = $row;
} else {
$result[$row[1]][0] .= ',' . $row[0];
}
return $result;
}
)
)
);
All will output:
array (
0 =>
array (
0 => '444,449,451',
1 => '0081',
),
1 =>
array (
0 => '455,469',
1 => '2100',
),
)

Loop through a multi dimensional array checking a specific key for repeat values in PHP

I have a multi dimensional array that I have got from a database and I want to check this array for duplicate data and store it in another array of duplicates. my code is as follows
//create temp array
$tmp = array();
foreach ($matchingarray as $nameKey => $match) {
// loop through and stoe the contents of that array to another so i can compare
$tmp[] = $match;
}
// create an array to store duplicates
$duplicatesArray = array();
// if the temp array is not empty then loop through both arrays
if (! empty($tmp)) {
foreach ($tmp as $key => $tmpvalue) {
foreach ($matchingarray as $key => $match) {
// if a key name is the same in both arrays then add it tothe duplicates array
if ($tmpvalue['name'] == $match['name']) {
$duplicatesArray = $match;
}
}
}
}
//count how many are duplicates
$dups = count($duplicatesArray);
What I would like to know is this the right logic?
I will take where Igoel left off
there is 1 error and also 1 suggest that i will make.
Error:
you cannot reuse $key twice in the foreach because they will override.
Suggestion as what Igoel stated: your best bet for duplicate effectively is to use sql. SQL is faster at processing than looping through arrays. Don't forget you need to load the data into memory and thats costly.
Try this way
<?php
static $cnt = array();
$min = 1;
$coll = array(
'dep1' => array(
'fy' => array('john', 'johnny', 'victor'),
'sy' => array('david', 'arthur'),
'ty' => array('sam', 'joe', 'victor')
),
'dep2' => array(
'fy' => array('natalie', 'linda', 'molly'),
'sy' => array('katie', 'helen', 'sam', 'ravi', 'vipul'),
'ty' => array('sharon', 'julia', 'maddy')
)
);
function recursive_search(&$v, $k){
global $cnt;
$cnt[] = $v;
}
array_walk_recursive($coll, 'recursive_search');
$newNumbers = array_filter(
array_count_values($cnt),
function ($value) use($min) {
return ($value > $min);
}
);
echo "Values > 1 are repeated \n";
print_r(array_count_values($cnt));
echo "Values repeted\n";
print_r($newNumbers);
DEMO

PHP: Get n-th item of an associative array

If you have an associative array:
Array
(
[uid] => Marvelous
[status] => 1
[set_later] => Array
(
[0] => 1
[1] => 0
)
[op] => Submit
[submit] => Submit
)
And you want to access the 2nd item, how would you do it? $arr[1] doesn't seem to be working:
foreach ($form_state['values']['set_later'] as $fieldKey => $setLater) {
if (! $setLater) {
$valueForAll = $form_state['values'][$fieldKey];
$_SESSION[SET_NOW_KEY][array_search($valueForAll, $form_state['values'])] = $valueForAll; // this isn't getting the value properly
}
}
This code is supposed to produce:
$_SESSION[SET_NOW_KEY]['status'] = 1
But it just produces a blank entry.
Use array_slice
$second = array_slice($array, 1, 1, true); // array("status" => 1)
// or
list($value) = array_slice($array, 1, 1); // 1
// or
$blah = array_slice($array, 1, 1); // array(0 => 1)
$value = $blah[0];
I am a bit confused. Your code does not appear to have the correct keys for the array. However, if you wish to grab just the second element in an array, you could use:
$keys = array_keys($inArray);
$key = $keys[1];
$value = $inArray[$key];
However, after considering what it appears you're trying to do, something like this might work better:
$ii = 0;
$setLaterArr = $form_state['values']['set_later'];
foreach($form_state['values'] as $key => $value) {
if($key == 'set_later')
continue;
$setLater = $setLaterArr[$ii];
if(! $setLater) {
$_SESSION[SET_NOW_KEY][$key] = $value;
}
$ii ++;
}
Does that help? It seems you are trying to set the session value if the set_later value is not set. The above code does this. Instead of iterating through the inner array, however, it iterates through the outer array and uses an index to track where it is in the inner array. This should be reasonably performant.
You can use array_slice to get the second item:
$a= array(
'hello'=> 'world',
'how'=> 'are you',
'an'=> 'array',
);
$second= array_slice($a, 1, 1, true);
var_dump($second);
Here's a one line way to do it with array_slice and current
$value = current(array_slice($array, 1, 1)); // returns value only
If the array you provide in the first example corresponds to $form_state then
$form_state['values']['set_later'][1]
will work.
Otherwise
$i = 0;
foreach ($form_state['values']['set_later'] as $fieldKey => $setLater) {
if ($i == 1) {
$valueForAll = $form_state['values'][$fieldKey];
$_SESSION[SET_NOW_KEY][$fieldKey] = $setLater;
continue;
}
$i++;
}
Every one of the responses here are focused on getting the second element, independently on how the array is formed.
If this is your case.
Array
(
[uid] => Marvelous
[status] => 1
[set_later] => Array
(
[0] => 1
[1] => 0
)
[op] => Submit
[submit] => Submit
)
Then you can get the value of the second element via $array['status'].
Also this code
foreach ($form_state['values']['set_later'] as $fieldKey => $setLater) {
if (! $setLater) {
$valueForAll = $form_state['values'][$fieldKey];
$_SESSION[SET_NOW_KEY][array_search($valueForAll, $form_state['values'])] = $valueForAll; // this isn't getting the value properly
}
}
I don't understand what are you trying to do, care to explain?
/**
* Get nth item from an associative array
*
*
* #param $arr
* #param int $nth
*
* #return array
*/
function getNthItemFromArr($arr, $nth = 0){
$nth = intval($nth);
if(is_array($arr) && sizeof($arr) > 0 && $nth > 0){
$arr = array_slice($arr,$nth-1, 1, true);
}
return $arr;
}//end function getNthItemFromArr

Get the first key for an element in PHP?

I'm trying to add an extra class tag if an element / value is the first one found in an array. The problem is, I don't really know what the key will be...
A minified example of the array
Array (
[0] => Array(
id => 1
name = Miller
)
[1] => Array(
id => 4
name = Miller
)
[2] => Array(
id => 2
name => Smith
[3] => Array(
id => 7
name => Jones
)
[4] => Array(
id => 9
name => Smith
)
)
So, if it's the first instance of "name", then I want to add a class.
I think I sort of understand what you're trying to do. You could loop through the array and check each name. Keep the names you've already created a class for in a separate array.
for each element in this array
if is in array 'done already' then: continue
else:
create the new class
add name to the 'done already' array
Sorry for the pseudo-code, but it explains it fairly well.
Edit: here's the code for it...
$done = array();
foreach ($array as $item) {
if (in_array($item['name'], $done)) continue;
// It's the first, do something
$done[] = $item['name'];
}
I assume you're looping through this array. So, a simple condition can be used:
$first = 0;
foreach ($arr as $value) {
if (!$first++) echo "first class!";
echo $value;
// The rest of process.
}
To get just the first value of an array, you can also use the old fashioned reset() and current() functions:
reset($arr);
$first = current($arr);
Animuson has it good. There a small addition if I might:
> $done = array();
> foreach ($array as $item) {
> if (in_array($item['name'], $done)) continue;
> // It's the first, do something
> $done[] = $item['name']; }
the in_array() will get slow very fast. Try something like:
$done = array();
foreach ($array as $item) {
$key = $item['name'];
if( !isset( $done[$key] )) {
...
}
$done[$key] = true;
}
btw. Too bad this site doesn't support comments for all users.

Categories