I have an multidimensional array and I need to count their specific value
Array
(
[0] => Array
(
[Report] => Array
(
[id] => 10
[channel] => 1
)
)
[1] => Array
(
[Report] => Array
(
[id] => 92
[channel] => 0
)
)
[2] => Array
(
[Report] => Array
(
[id] => 18
[channel] => 0
)
)
[n] => Array
)
I need to get output like that: channel_1 = 1; channel_0 = 2 etc
I made a function with foreach:
foreach ($array as $item) {
echo $item['Report']['channel'];
}
and I get: 1 0 0 ... but how can I count it like: channel_1 = 1; channel_0 = 2, channel_n = n etc?
Try this. See comments for step-by-step explanation.
Outputs:
array(2) {
["channel_1"]=>
int(1)
["channel_0"]=>
int(2)
}
Code:
<?php
// Your input array.
$a =
[
[
'Report' =>
[
'id' => 10,
'channel' => 1
]
],
[
'Report' =>
[
'id' => 92,
'channel' => 0
]
],
[
'Report' =>
[
'id' => 18,
'channel' => 0
]
]
];
// Output array will hold channel_N => count pairs
$result = [];
// Loop over all reports
foreach ($a as $report => $values)
{
// Key takes form of channel_ + channel number
$key = "channel_{$values['Report']['channel']}";
if (!isset($result[$key]))
// New? Count 1 item to start.
$result[$key] = 1;
else
// Already seen this, add one to counter.
$result[$key]++;
}
var_dump($result);
/*
Output:
array(2) {
["channel_1"]=>
int(1)
["channel_0"]=>
int(2)
}
*/
You can easily do this without a loop using array_column() and array_count_values().
$reports = array_column($array, 'Report');
$channels = array_column($reports, 'channel');
$counts = array_count_values($channels);
$counts will now equal an array where the key is the channel, and the value is the count.
Array
(
[1] => 1
[0] => 2
)
Related
How to update an array of objects, adding the quantities if you already have the same ID, or if you have not created a new object.
I tried to explain in the code with the arrays and also with the idea of how I would like the result to be.
old Array
$a1 = [
array(
"id" => 1,
"qty" => 1
),
array(
"id" => 2,
"qty" => 1
)
];
$a2 = [
array(
"id" => 1,
"qty" => 1
)
];
$output = array_merge($a1, $a2);
echo '<pre>';
print_r($output);
echo '</pre>';
Result Error:
Array
(
[0] => Array
(
[id] => 1
[qty] => 1
)
[1] => Array
(
[id] => 2
[qty] => 1
)
[2] => Array
(
[id] => 1
[qty] => 1
)
)
What I need, in addition to if the ID does not contain, add.
Array
(
[0] => Array
(
[id] => 1
[qty] => 2
)
[1] => Array
(
[id] => 2
[qty] => 1
)
)
You can take the first array as base, then search for the key (if existing) where the product matches the id. Then either add the quantity and recalculate the price or you just add the reformatted element (id to product conversion).
$result = $a;
foreach($b as $element) {
$matchingProductIndex = array_search($element['id'], array_column($a, 'product'));
if ($matchingProductIndex !== false) {
$pricePerUnit = $result[$matchingProductIndex]['price'] / $result[$matchingProductIndex]['qty'];
$result[$matchingProductIndex]['qty'] += $element['qty'];
$result[$matchingProductIndex]['price'] = $result[$matchingProductIndex]['qty'] * $pricePerUnit;
} else {
$result[] = [
'qty' => $element['qty'],
'product' => $element['id'],
'price' => $element['price'],
];
}
}
print_r($result);
Working example.
Loop through both arrays with foreach and check the ids against each other.
https://paiza.io/projects/lnnl5HeJSFIOz_6KD6HRIw
<?php
$arr1 = [['qty' => 4, 'id' => 4],['qty' => 1,'id' => 30]];
$arr2 = [['id' => 30, 'qty' => 19],['id' => 31, 'qty' => 2]];
$arr3 = [];
foreach($arr1 as $iArr1){
$match = false;
foreach($arr2 as $iArr2){
if($iArr1['id'] === $iArr2['id']){
$arr3[] = ['id' => $iArr1['id'], 'qty' => $iArr1['qty'] + $iArr2['qty']];
$match = true;
}
}
if(!$match){
$arr3[] = $iArr1;
$arr3[] = $iArr2;
}
}
print_r($arr3);
?>
One approach could be one I more often suggested.
First lets merge $a2 with one to simplify looping over one larger collection.
If we then create a small mapping from id to its index in the result array we can update the running total of qty.
$map = [];
$result = [];
// Merge the two and do as per usual, create a mapping
// from id to index and update the qty at the corresponding index.
foreach (array_merge($a1, $a2) as $subarr) {
$id = $subarr['id'];
if (!key_exists($id, $map)) {
$index = array_push($result, $subarr) - 1;
$map[$id] = $index;
continue;
}
$result[$map[$id]]['qty'] += $subarr['qty'];
}
echo '<pre>', print_r($result, true), '</pre>';
Output:
Array
(
[0] => Array
(
[id] => 1
[qty] => 2
)
[1] => Array
(
[id] => 2
[qty] => 1
)
)
I am trying to add my data to my array inside my foreach loop.
I have almost done it successfully, except the array is too in-depth.
It's showing array->array->{WHAT I WANT}
When I need array->{WHAT I WANT}
Example, I'm needing it to be like:
Array
(
[home] => Array
(
[0] => Dashboard\Main#index
[1] => GET
)
[home/] => Array
(
[0] => Dashboard\Main#index
[1] => GET
)
)
When at the moment, it's showing:
Array
(
[0] => Array
(
[services/content-writing] => Array
(
[0] => Dashboard\Services#contentwriting
[1] => GET
)
)
[1] => Array
(
[services/pbn-links] => Array
(
[0] => Dashboard\Services#pbnlinks
[1] => GET
)
)
)
The code I'm currently using inside my foreach loop is:
$realArray = array();
// Services exist
if($services)
{
// Sort them into our array
foreach ($services as $service) {
$servicePageName = $service->page_name;
$serviceName = str_replace(' ', '', strtolower($service->name));
$realArrayNew = array(
"services/$servicePageName" => ["Dashboard\Services#$serviceName", 'GET']
);
array_push($realArray, $realArrayNew);
//'home' => ['Dashboard\Main#index', 'GET'],
}
}
return $realArray;
The servicePageName variable must be the key field on the realArray to get the results you want.
I'm presuming you input object array looks something like this:
[
(int) 0 => object(stdClass) {
name => 'contentwriting'
page_name => 'content-writing'
},
(int) 1 => object(stdClass) {
name => 'pbnlinks'
page_name => 'pbn-links'
}
]
If we do this:
$realArray = [];
if ($services) {
foreach ($services as $service) {
$servicePageName = $service->page_name;
$serviceName = str_replace(' ', '', strtolower($service->name));
$realArray["services/$servicePageName"] = [
0 => "Dashboard\Services#$serviceName",
1 => "GET"
];
}
}
This is what we get on realArray:
[
'services/content-writing' => [
(int) 0 => 'Dashboard\Services#contentwriting',
(int) 1 => 'GET'
],
'services/pbn-links' => [
(int) 0 => 'Dashboard\Services#pbnlinks',
(int) 1 => 'GET'
]
]
This portion of the code inserts a new subarray to your main array:
$realArrayNew = array(
"services/$servicePageName" => ["Dashboard\Services#$serviceName", 'GET']
);
array_push($realArray, $realArrayNew);
Replace it all with:
$realArray["services/$servicePageName"] = ["Dashboard\Services#$serviceName", 'GET'];
That way your top level will have service names as keys.
I need to take an array like this:
Array
(
[0] => Array
(
[county_code] => 54045
[count] => 218
)
[1] => Array
(
[county_code] => 54045
[count] => 115
)
[2] => Array
(
[county_code] => 54051
[count] => 79
)
)
And merge all arrays with the same county_code adding the count, like this:
Array
(
[0] => Array
(
[county_code] => 54045
[count] => 333
)
[1] => Array
(
[county_code] => 54051
[count] => 79
)
)
There will be multiple instances of multiple county codes.
Can anyone point me in the right direction?
Try this out:
// your example array
$array = [
[
"county_code" => 54045,
"count" => 218
],
[
"county_code" => 54045,
"count" => 115
],
[
"county_code" => 54051,
"count" => 79
]
];
// intrim step to collect the count.
$intrimArray = [];
foreach( $array as $data ){
$countyCode = $data["county_code"];
if (!$intrimArray[$countyCode]) {
$intrimArray[$countyCode] = $data["count"];
} else {
$intrimArray[$countyCode] = $intrimArray[$countyCode] + $data["count"];
}
}
// build the final desired array using interim array.
$finalArray = [];
foreach($intrimArray as $countyCode => $totalCount) {
array_push($finalArray, [
"county_code" => $countyCode,
"count" => $totalCount
]);
}
var_dump($finalArray);
As promised:
<?php
$initial_array = [
['country_code' => 54045, 'count' => 218],
['country_code' => 54045, 'count' => 115],
['country_code' => 54051, 'count' => 79],
];
$synth = [];
foreach ($initial_array as $sa) { # $sa: subarray
if (!isset($synth[$sa['country_code']])) {
$synth[$sa['country_code']] = 0;
}
$synth[$sa['country_code']] += $sa['count'];
}
print_r($synth); # Synthesis array: keys are country codes, values are cumulative counts.
# If you need the same format for both the initial and synthesis arrays, then continue with this:
$synth2 = [];
foreach ($synth as $k => $v) {
$synth2[] = ['country_code' => $k, 'count' => $v];
}
print_r($synth2);
?>
A fiddle for this code: https://3v4l.org/M8tkb
Best regards
This is how my array looks like :
Array
(
[0] => Array
(
[unit] => 10
[harga] => 15000
)
[1] => Array
(
[unit] => 7
[harga] => 10000
)
[2] => Array
(
[unit] => 12
[harga] => 123123
)
)
I want to unset the 0 key array when the unit is 0 and rearrange the key so the 1 key will replace the 0.
This is how I do it :
$jumlah_penjualan = $data - > unit;
while ($jumlah_penjualan > 0) {
$persediaan_pertama = $persediaan[0]['unit'];
$harga_persediaan = $persediaan[0]['harga'];
if ($persediaan_pertama < $jumlah_penjualan) {
$dijual = $persediaan_pertama;
$penjualan[] = array(
'unit' => $dijual,
'harga' => $harga_persediaan,
'total' => $dijual * $harga_persediaan);
$persediaan[0]['unit'] = $persediaan[0]['unit'] - $dijual;
} else {
$dijual = $jumlah_penjualan;
$penjualan[] = array(
'unit' => $dijual,
'harga' => $harga_persediaan,
'total' => $dijual * $harga_persediaan);
$persediaan[0]['unit'] = $persediaan[0]['unit'] - $dijual;
}
if ($persediaan[0]['unit'] == 0) {
unset($persediaan[0]);
$persediaan = array_values($persediaan);
}
$jumlah_penjualan = $jumlah_penjualan - $dijual;
}
But the result looks like it continues looping before rearranging the array.
This is how the array should look like after unset:
Array(
[0] => Array
(
[unit] => 9
[harga] => 123123
)
)
If you want to remove the first elements until the unit is not 0, you can
$arr = array
(
array
(
"unit" => 0,
"harga" => 15000
),
array
(
"unit" => 0,
"harga" => 10000
),
array
(
"unit" => 12,
"harga" => 123123
)
);
while( $arr[0]["unit"] == 0 ) { //Loop until $arr[0]["unit"] is not 0
unset($arr[0]); //Remove $arr[0] since unit is 0
$arr = array_values($arr); //Make Make element 1 to element 0
}
echo "<pre>";
print_r( $arr );
echo "</pre>";
This will result to:
Array
(
[0] => Array
(
[unit] => 12
[harga] => 123123
)
)
To remove the first element of an array and reindex the elements, use array_shift. First, check that the number of units are zero, then remove the first element if that's the case.
if ($arr[0]['unit'] == 0) {
array_shift($arr);
}
Since it's impossible to say what your other variables even mean because of the language, you probably want to move this outside of your while loop, so that the first element is only removed after you've processed the array.
I have 2 array's, first array have for example ItemID of my item, second array have description about my item. I want to match data into 1 array.
It looks like:
[rgInventory] => Array
(
[1234567890] => Array
(
[id] => 1234567890
[classid] => 123456789
[instanceid] => 987654321
[amount] => 1
[pos] => 1
)
)
[rgDescriptions] => Array
(
[192837465_918273645] => Array
(
[appid] => 730
[name] => Something
)
)
Items in arrays don't have the same value like ID, but they are in the same order so:
Description for the first item in rgInventory is in the first array inside rgDescriptions.
What should I do to match for example id from rgInventory with name from rgDescriptions in the same array for example $backpack = array();?
Regards for you.
Try this:
<?php
$array1 = array('rgInventory' =>
array(
'1234567890' => array(
'id' => 1234567890,
'classid' => 123456789,
'instanceid' => 987654321,
'amount' => 1,
'pos' => 1
)
)
);
$array2 = array(
'rgDescriptions' => array(
'192837465_918273645' => array(
'appid' => 730, 'name' => 'Something')
)
);
Create new function to combine the two arrays into one array:
function array_sum_recursive($data1, $data2) {
if (!is_array($data1) && !is_array($data2)) {
return $data1 + $data2;
}
// deepest array gets precedence
if (!is_array($data2)) {
return $data1;
}
if (!is_array($data1)) {
return $data2;
}
//merge and remove duplicates
$keys = array_unique(array_merge(array_keys($data1), array_keys($data2)));
foreach ($keys as $key) {
if (isset($data1[$key]) && isset($data2[$key])) {
$result[$key] = array_sum_recursive($data1[$key], $data2[$key]);
} else if (isset($data1[$key])) {
$result[$key] = $data1[$key];
} else {
$result[$key] = $data2[$key];
}
}
if(empty($result)){
echo "no result";
die();
}else{
return $result;
}
}
Put the two array in one array $newarray:
$newonearray = array_sum_recursive($array1, $array2);
echo '<pre>';
print_r($newonearray);
?>
And you will get this:
Array
(
[rgInventory] => Array
(
[1234567890] => Array
(
[id] => 1234567890
[classid] => 123456789
[instanceid] => 987654321
[amount] => 1
[pos] => 1
)
)
[rgDescriptions] => Array
(
[192837465_918273645] => Array
(
[appid] => 730
[name] => Something
)
)
)
Hope this may help.
You can use function each to get each element of both arrays, then merge its with array_merge and save this new item to backup array.
Try something like this
<?php
$rgInventory = ['firstInv' => ['invId' => 1], 'secondInv' => ['invId' => 2]];
$rgDescriptions = ['firstDesc' => ['descId' => 1], 'secondDesc' => ['descId' => 2]];
if (count($rgInventory) && count($rgInventory) == count($rgDescriptions)) {
$backpack = [];
while($inventory = each($rgInventory)) {
$description = each($rgDescriptions);
$item = array_merge($inventory['value'], $description['value']);
$backpack[] = $item;
}
var_dump($backpack);
}
Output will be:
array(2) {
[0]=>
array(2) {
["invId"]=>
int(1)
["descId"]=>
int(1)
}
[1]=>
array(2) {
["invId"]=>
int(2)
["descId"]=>
int(2)
}
}