I am trying to get the count and values of stocklevels from the following
Array ( [barcodes] => Array ( [barcode] => 10011010009 ) [basePrice] => 25.00 [customFields] => Array ( ) [description] => CBC-CBCJSW [discontinued] => false [PLU] => CBC Boy's Shirt 20 [priceLevels] => Array ( ) [primaryCategory] => CBC- Boys Shirts [productLineName] => CBC Boy's Shirt 20 [promptPOSOperatorForPrice] => false [sellByWeightOption] => false [stock] => Array ( [stockLevel] => Array ( [0] => Array ( [outletExportCode] => Level1 [stockCount] => 500.000000 ) [1] => Array ( [outletExportCode] => Level2 [stockCount] => 1000.000000 ) ) ) [taxes] => Array ( [taxName] => GST ) )
I have tried the following and i get 1 as the count all the time even if there are 2 levels in the array:
count($ra['stock']['stockLevel']['stockCount']);
count($ra['stock']['stockLevel']);
Also, i am trying to loop through the results to get teh stockcount but it doesnt seem to work:
$stockLevelArr[] = $ra['stock'];
$totalStock = 0;
for($i=0;$i<count($stockLevelArr);$i++){
echo $ra['productLineName'] . ' - Stock outside IF: ' . (int) $stockLevelArr[$i]['stockLevel']['stockCount'];
echo '<br>';
if (isset($stockLevelArr[$i]['stockLevel']['stockCount'])) {
$totalStock = $totalStock + $stockLevelArr[$i]['stockLevel']['stockCount'];
}
}
echo 'Stock count: ' . $totalStock;
echo '<br>';
var dump
array(13) { ["barcodes"]=> array(1) { ["barcode"]=> string(11) "10011010009" } ["basePrice"]=> string(5) "25.00" ["customFields"]=> array(0) { } ["description"]=> string(10) "CBC-CBCJSW" ["discontinued"]=> string(5) "false" ["PLU"]=> string(18) "CBC Boy's Shirt 20" ["priceLevels"]=> array(0) { } ["primaryCategory"]=> string(16) "CBC- Boys Shirts" ["productLineName"]=> string(18) "CBC Boy's Shirt 20" ["promptPOSOperatorForPrice"]=> string(5) "false" ["sellByWeightOption"]=> string(5) "false" ["stock"]=> array(1) { ["stockLevel"]=> array(2) { [0]=> array(2) { ["outletExportCode"]=> string(13) "Tara Uniforms" ["stockCount"]=> string(10) "500.000000" } [1]=> array(2) { ["outletExportCode"]=> string(3) "CBC" ["stockCount"]=> string(11) "1000.000000" } } } ["taxes"]=> array(1) { ["taxName"]=> string(3) "GST" } }
I will appreciate any help.
UPDATE: Following worked. Thanks everyone for your replies and assistance.
$totalStock = 0;
$times_found = 0;
$stock = $ra['stock'];
foreach($stock['stockLevel'] as $stock_level) {
if(isset($stock_level['stockCount'])) {
$times_found++;
$totalStock = $totalStock + $stock_level['stockCount'];
}
}
I'm assuming you mean you want to know how many times stockCount is within the array? If so, I'd use array to loop through each index of the array and increment a variable each time it's found. For example:
$times_found = 0;
foreach($ra['stock'] as $stock) {
foreach($stock['stockLevel'] as $stock_level) {
if(isset($stock_level['stockCount'])) {
$times_found++;
}
}
}
You should count recursive to get all the keys in the count:
count($ra, COUNT_RECURSIVE);
See also the php manual https://www.php.net/manual/en/function.count.php
And I think you should change your for loop to this:
<?php
$totalStock = 0;
foreach ($ra['stock'] as $stock) {
echo $ra['productLineName'] . ' - Stock outside IF: ' . (int) $stock['stockLevel']['stockCount'];
echo '<br>';
if (isset($stock['stockLevel']['stockCount'])) {
$totalStock = $totalStock + $stock['stockLevel']['stockCount'];
}
}
echo 'Stock count: ' . $totalStock;
echo '<br>';
Instead of the for loop, dont know why you did use that, you better use the foreach in this example.
Related
I have an array like this :
array(3) {
["FL_1"] => array(3) {
["MIC_1"] => array(1) {
["SP_4"] => float(7)
}
["MIC_13"] => array(1) {
["SP_16"] => float(4)
}
["MIC_6"] => array(1) {
["SP_74"] => float(4)
}
}
["FL_2"] => array(2) {
["MIC_1"] => array(1) {
["SP_5"] => float(4)
}
["MIC_13"] => array(1) {
["SP_17"] => float(4)
}
["MIC_6"] > array(1) {
["SP_75"] => float(4)
}
}
["FL_3"] => array(2) {
["MIC_1"] => array(1) {
["SP_5"] => float(89)
}
["MIC_13"] => array(1) {
["SP_18"] => float(1)
}
["MIC_6"] > array(1) {
["SP_78"] => float(21)
}
}
}
For each FL_X, I need to keep only one MIC_X that follow the conditions below :
1- This MIC_X needs to be the same for each FL_X
2- This MIC_X needs to have the lowest possible SP_Xvalue
From this example I need to get the following array
array(3) {
["FL_1"] => array(1) {
["MIC_13"] => array(1) {
["SP_16"] => float(4)
}
}
["FL_2"] => array(1) {
["MIC_13"] => array(1) {
["SP_17"] => float(6)
}
}
["FL_3"] => array(1) {
["MIC_13"] => array(1) {
["SP_18"] => float(1)
}
}
}
Any help on how to do this would be much appreciated.
Thank you !
Here's one possible solution. It uses array_walk_recursive to find the SP_X key associated with the minimum SP_X value, then it traverses the array to find the MIC_X key associated with that SP_X key and value, and finally it uses array_map and array_filter to extract only those MIC_X key values from the original array:
// find the minimum SP_X value and its key
$min_sp = PHP_INT_MAX;
$min_key = '';
array_walk_recursive($array, function ($v, $k) use (&$min_sp, &$min_key) {
if ($v < $min_sp) {
$min_sp = $v;
$min_key = $k;
}
});
// find the MIC_X key corresponding to the min SP_X value
$mic_key = '';
foreach ($array as $fl) {
foreach ($fl as $mic => $sp) {
if (isset($sp[$min_key]) && $sp[$min_key] == $min_sp) {
$mic_key = $mic;
break 2;
}
}
}
// filter the array to get all the MIC_X values
$out = array_map(function ($fl) use ($mic_key) {
return array_filter($fl, function ($mic) use ($mic_key) {
return $mic == $mic_key;
}, ARRAY_FILTER_USE_KEY);
}, $array);
print_r($out);
Output:
Array
(
[FL_1] => Array
(
[MIC_13] => Array
(
[SP_16] => 4
)
)
[FL_2] => Array
(
[MIC_13] => Array
(
[SP_17] => 4
)
)
[FL_3] => Array
(
[MIC_13] => Array
(
[SP_18] => 1
)
)
)
Demo on 3v4l.org
I have a text file named C.txt. The contens of the text file goes as following:
Name, BPrice, SPrice, Display
Nokia 520, 20000, 21000, 1
Xiaomi123, 15000, 17000, 0
Xiaomi Redmi, 30000, 32000, 1
I have accessed the file using the following code:
<?php
$file = fopen("C.txt", "r");
while(!feof($file)){
$content = fgets($file);
$products[] = $content;
}
var_dump($products);
?>
var_dump($products) gives output:
array(4) { [0]=> string(33) "Name, BPrice, SPrice, Display " [1]=> string(29) "Nokia 520, 20000, 21000, 1 " [2]=> string(29) "Xiaomi123, 15000, 17000, 0 " [3]=> string(30) "Xiaomi Redmi, 30000, 32000, 1 " }
What I wanted to do, is to separate the Name, BPrice, SPrice and Display columns and their values using explode() method. So, I tried the following:
<?php
for($i=1; $i<count($products); $i++){
$contents[] = explode(",", $products[$i]);
}
var_dump($contents);
?>
var_dump($contents) yields:
array(3) { [0]=> array(4) { [0]=> string(9) "Nokia 520" [1]=> string(6) " 20000" [2]=> string(6) " 21000" [3]=> string(5) " 1 " } [1]=> array(4) { [0]=> string(9) "Xiaomi123" [1]=> string(6) " 15000" [2]=> string(6) " 17000" [3]=> string(5) " 0 " } [2]=> array(4) { [0]=> string(12) "Xiaomi Redmi" [1]=> string(6) " 30000" [2]=> string(6) " 32000" [3]=> string(3) " 1 " } }
NOTE: I wanted to access only the values of the columns and not the headers, hence for($i=1; $i<count($products); $i++)
Now here is where I'm facing the problem. How do I access this two dimensional array $contents?
I have tried the foreach loop as following:
foreach ($contents as $key => $value) {
echo $value[$key];
}
But that results in:
Nokia 520 15000 32000
I cannot seem to figure out why it is not printing the rest of the two rows! Any help would be greatly appreciated. Thanks in advance! :)
Your problem is in the echo $value[$key];.
The $key variable in this context holds the key of current $contents array member, while you are using it to access the value of the inside array, the product data.
Since this is a multi-dimensional array, you will need multiple loops to print it all out. So if you'd like to do that, it would work like this:
foreach ($contents as $productValues) {
foreach ($productValues as $productValue) {
echo $productValue;
}
echo PHP_EOL;
}
Try this function for parsing cvs files into an associative array with the column names as array keys:
function csvArray($file) {
$csv = array_map('str_getcsv', file($file));
array_walk($csv, function(&$a) use ($csv) {
$a = array_combine($csv[0], $a);
});
array_shift($csv);
return $csv;
}
Then result of
$phones = csvArray('c.txt');
print_r($phones);
Is:
Array
(
[0] => Array
(
[Name] => Nokia 520
[ BPrice] => 20000
[ SPrice] => 21000
[ Display] => 1
)
[1] => Array
(
[Name] => Xiaomi123
[ BPrice] => 15000
[ SPrice] => 17000
[ Display] => 0
)
[2] => Array
(
[Name] => Xiaomi Redmi
[ BPrice] => 30000
[ SPrice] => 32000
[ Display] => 1
)
)
Your array in more readable terms looks like this
[["Nokia 520", "20000", "21000", "1"],
["Xiaomi123", "15000", "17000", "0"],
["Xiaomi Redmi", "30000", "32000", "1"]]
This means that in your foreach, the value of your first key is
["Nokia 520", "20000", "21000", "1"]
The reason you are only getting those values is that you are doing
echo $value[$key];
So essentially you are returning positions 0 1 and 2 of ["Nokia 520", "20000", "21000", "1"], which are the values Nokia 520, 20000 and 21000
To get the values you actually want, you need to perform two foreach loops
foreach ($arr as $keys) {
foreach($keys as $value) {
echo "{$value} ";
}
echo "\n";
}
How can I add cummalatively this array below :
array
Product 1 =>
array
0 => float 8065.45
Product 2 =>
array
0 => float 8065.45
array
Product 1 =>
array
0 => float 8065.45
array
0 => float 158.65
Product 2 =>
array
0 => float 8065.45
array
0 => float 11736.37
I am currently using array_sum for this but I think its not working.
use foreach and array_sum to sum it.
$sum = 0;
foreach($products as $product)
{
foreach($product as $v)
{
$sum += array_sum($v);
}
}
By "adding cummulatively", I think you mean appending.
So, giving you example:
<?php
$products = [
'Product 1' => [8065.45],
'Product 2' => [8065.45]
];
var_dump($products);
$products['Product 1'][] = 158.65;
$products['Product 2'][] = 11736.37;
var_dump($products);
It should returns:
array(2) {
["Product 1"] => array(1) {
[0]=> float(8065.45)
}
["Product 2"] => array(1) {
[0]=> float(8065.45)
}
}
array(2) {
["Product 1"] => array(2) {
[0]=> float(8065.45)
[1]=> float(158.65)
}
["Product 2"] => array(2) {
[0]=> float(8065.45)
[1]=> float(11736.37)
}
}
You can also use the array_push() function.
I have the following multi-dimensional array and I need to iterate over it and wherever there is a duplicate name, a counter is added to the name.
[1] => Array
(
[0] => Array
(
[clientName] => John Smith
[clientType] => 0
[clientDOB] => 1980-10-14
)
)
[2] => Array
(
[0] => Array
(
[clientName] => John Smith
[clientType] => 0
[clientDOB] => 1970-01-01
)
[1] => Array
(
[clientName] => Jeremy White
[clientType] => 2
[clientDOB] => 2015-08-19
)
)
The code I'm using is this :
$finalNames = array_map(function ($item) use (&$namesCount) {
if (!isset($namesCount[$item['clientName']])) {
$namesCount[$item['clientName']] = 0;
}
$namesCount[$item['clientName']]++;
$item['clientName'] = $item['clientName'] . ' ' . $namesCount[$item['clientName']];
return $item;
}, $arrayOfTravellers);
array_map(function($item, $key) use ($namesCount, &$finalNames) {
$finalNames[$key]['clientName'] = $namesCount[$item['clientName']] == 1
? str_replace(' 1', '', $finalNames[$key]['clientName'])
: $finalNames[$key]['clientName'];
}, $arrayOfNames, array_keys($arrayOfTravellers));
Which is returning a bunch of errors such as :
Notice: Undefined index: clientName in /Applications/MAMP/htdocs/europatours/functions/reportsFunctions.php on line 330
My assumption is that the code is not fit for a multi-dimensional array. Can anyone help please? I need to retain the complete structure of the array only where there is a duplicate name, a counter is added such as John Smith 1, John Smith 2 whereas Jeremy White remains without a counter.
$arrayOfNames = array(
array('clientName' => 'John'),
array('clientName' => 'John'),
array('clientName' => 'Mary'),
array('clientName' => 'Mary'),
array('clientName' => 'Mary'),
array('clientName' => 'Tony'),
array('clientName' => 'Alex')
);
$namesCount = array();
$finalNames = array_map(function ($item) use (&$namesCount) {
if (!isset($namesCount[$item['clientName']])) {
$namesCount[$item['clientName']] = 0;
}
$namesCount[$item['clientName']]++;
$item['clientName'] = $item['clientName'] . ' ' . $namesCount[$item['clientName']];
return $item;
}, $arrayOfNames);
array_map(function($item, $key) use ($namesCount, &$finalNames) {
$finalNames[$key]['clientName'] = $namesCount[$item['clientName']] == 1
? str_replace(' 1', '', $finalNames[$key]['clientName'])
: $finalNames[$key]['clientName'];
}, $arrayOfNames, array_keys($arrayOfNames));
echo '<pre>';
var_dump($finalNames);
echo '</pre>';
The output would be:
array(7) {
[0]=>
array(1) {
["clientName"]=>
string(6) "John 1"
}
[1]=>
array(1) {
["clientName"]=>
string(6) "John 2"
}
[2]=>
array(1) {
["clientName"]=>
string(6) "Mary 1"
}
[3]=>
array(1) {
["clientName"]=>
string(6) "Mary 2"
}
[4]=>
array(1) {
["clientName"]=>
string(6) "Mary 3"
}
[5]=>
array(1) {
["clientName"]=>
string(4) "Tony"
}
[6]=>
array(1) {
["clientName"]=>
string(4) "Alex"
}
}
What about a combination of array_column and in_array when adding new values?
$records = array(); // your data
$name = 'John';
$i = 0;
do
{
$newName = $name . ( ($i == 0)? '' : ' '.$i );
$i++;
}
while (in_array($newName, array_column($records, 'clientName')));
$records[] = array('clientName' => $newName);
Due to performance issues you may want to call array_columns only once before the loop and store the results in a variable.
The following array contains several languages and another string named "Music". I want to add the text " News" right behind every language that is inside cat_name.
In the end the text should become "German News" etc., but "Music" should not become "Music News".
How can I add the text " News" for objects that were checked to contain "German", "Japanese", or "Chinese" in it's cat_name?
The key number is unknown.
array(2) {
[0]=>
object(stdClass)#3051 (17) {
["cat_name"]=>
&string(11) "German"
}
[1]=>
object(stdClass)#3068 (17) {
["cat_name"]=>
&string(4) "Chinese"
}
[2]=>
object(stdClass)#3068 (17) {
["cat_name"]=>
&string(15) "Japanese"
}
[3]=>
object(stdClass)#3068 (19) {
["cat_name"]=>
&string(15) "Music"
}
}
This is the code I tried (without success):
foreach ($array as $key=>$cat){
if (in_array($cat->cat_name, array('German', 'Japanese', 'Chinese'))){ $array['cat_name'] .= ' News';}}
Use a for loop with an if statement specifically to exclude Music:
$array = array(
array('cat_name' => 'English'),
array('cat_name' => 'Music')
);
for ($i=0; $i < sizeof($array); $i++) {
if ($array[$i]['cat_name'] != 'Music')
$array[$i]['cat_name'] .= ' News';
}
print_r($array);
Output:
Array
(
[0] => Array
(
[cat_name] => English News
)
[1] => Array
(
[cat_name] => Music
)
)
$array = array(
array('cat_name' => 'English'),
array('cat_name' => 'Music')
);
$i=0;
foreach ($array as $key=>$cat){
if($cat['cat_name'] !='Music'){
$arrayy[$i]['cat_name'] = $cat['cat_name'].' News';
} else {
$arrayy[$i]['cat_name'] = $cat['cat_name'];
}
$i++;
}
print_r($arrayy);