PHP add counter to name if already exists in array - php

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.

Related

how to split a string and build an associative array php?

How to split a string in PHP ? For example, if i have the string like
Array([0] => "1=>10,2=>9,3=>7,1=>9,2=>8,3=>7");
how can i get
Array([0] => 1=>10,2=>9,3=>7 [1] => 1=>9,2=>8,3=>7);
and later i want to build an associative array like for example,
$ratings = array(6533 => ['Build Quality' => [1=>10,2=>9,3=>7],
'Versatility' => [1=>9,2=>8,3=>7],
'value' => [1=>9.5,2=>7,3=>6]]);
//takes the current post id and returns an product ratings array
function get_ratings($current_post_id){
$product_post = get_post($current_post_id);
preg_match_all("/\[v360_product_table\s.*?\]/", $product_post>post_content, $product_elements);
$product_elements = $product_elements[0][0];
preg_match_all('/"([^"]+)"/', $product_elements, $parameters);
$product_params = $parameters[0][0];
$rating_params = preg_split('","', $product_params);
$rating_factors = str_replace('"', '', $rating_params);
$b = print_r($rating_factors);
/* output: Array ( [0] => Build Quality [1] => Versatality [2] => Adoptability) */
$product_rank = $parameters[0][1];
/* output: Array ( [0] => 1=>10,2=>9,3=>7,1=>9,2=>8,3=>7 ) */
$rank_split = preg_split('"**have to split it here**"', $product_rank);
$rank_values = str_replace('"', '', $rank_split);
$assoc_array = array_combine($rating_factors, $rank_values);
/* needs to construct an array like '$ratings' */
$ratings = array(6533 => ['Build Quality' => [1 => 10, 2 => 8, 3 => 7],
'Versatility' => [1 => 9, 2 => 9, 3 => 8], 'Value' => [1 => 10, 2 => 8,3 => 8]]);
return $ratings[$current_post_id];
}
From your examples, I'm guessing you want to split the string by commas followed by the number 1. To do this, you can use preg_split() with a positive lookahead:
$string = "1=>10,2=>9,3=>7,1=>9,2=>8,3=>7";
$split = preg_split('/,(?=1\b)/', $string);
var_dump($split);
Gives:
array(2) {
[0]=>
string(15) "1=>10,2=>9,3=>7"
[1]=>
string(14) "1=>9,2=>8,3=>7"
}
This function will parse out the whole string into a nested array:
function split_string($string)
{
$split = array();
foreach (preg_split('/,(?=1\b)/', $string) as $row => $part1) {
foreach (explode(',', $part1) as $part2) {
list($key, $value) = explode('=>', $part2, 2);
$split[$row][$key] = $value;
}
}
return $split;
}
Tested as follows (in php 5.6):
$string = "1=>10,2=>9,3=>7,1=>9,2=>8,3=>7";
$split = split_string($string);
var_dump($split);
Gives this output:
array(2) {
[0]=>
array(3) {
[1]=>
string(2) "10"
[2]=>
string(1) "9"
[3]=>
string(1) "7"
}
[1]=>
array(3) {
[1]=>
string(1) "9"
[2]=>
string(1) "8"
[3]=>
string(1) "7"
}
}
You could then use array_combine() for example to merge in the names:
$string = "1=>10,2=>9,3=>7,1=>9,2=>8,3=>7";
$split = split_string($string);
var_dump(array_combine(array('Build Quality', 'Versatility'), $split));

PHP Cant get the count of array child elements

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.

How can I add some text to the end of a string of an array?

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);

how to do the calculation in an array

I have an array :
Array
(
[0] => Array
(
[batch_id] => 1
[seq_id] => 1
[q_id] => 2046
[a1] => 0
[a2] => 1
[a3] => 2
[a4] => 3
[a5] => 4
)
)
I need to minus the value of a1-a5 by 1
desire result(e.g. a1):
array(4) {
["w_id"]=>
string(5) "99911"
["q_id"]=>
string(4) "2046"
["c_id"]=>
string(6) "a1"
["rank"]=>
int(1) "-1"
}
My code is as follow:
$result = mysql_query("Select * from table_1");
while($cr = mysql_fetch_array($result)){
$rr_id = $cr['batch_id'].$cr['seq_id'];
$rid = '999'.$rr_id;
$q_id = $cr['q_id'];
foreach ($cr as $k => $v){
if(preg_match('{^a\d+$}',$k)){
$new_insert[] = array(
'w_id'=>$rid,
'q_id' =>$q_id,
'c_id' =>$k,
'rank'=>$v-1
);
}
}
However, the result of rank becomes
array(4) {
["w_id"]=>
string(5) "99911"
["q_id"]=>
string(4) "2046"
["c_id"]=>
string(6) "a1"
["rank"]=>
int(0)
}
Cannot show the value of rank
Any problem with my code??Can someone answer my question thank you very much
You can use :
$data = array_map(function ($v) {
foreach($v as $k => &$x) {
if (preg_match('{^a\d+$}', $k)) {
$x = $x - 1;
}
}
return $v;
}, $data);
print_r($data);
Live Demo
preg_match('{^Item \d+$}',$k)
You've got wrong pattern inside preg_match (keys you are looking for are 'a1','a2'... not 'item 1', 'item 2'...), just use this one:
preg_match('{^a\d+$}',$k)
Just use loop and pre decrementation
foreach($cr as $k=>&$v)
{
--$v['a1'];--$v['a2'];--$v['a3'];--$v['a4'];--$v['a5'];
}
print_r($cr);
I use $cr as your array.
$cr[] = array("batch_id"=>1, "seq_id"=>1, "q_id"=>'2046', "a1"=>1,"a2"=>1,"a3"=>1,"a4"=>1,"a5"=>1);
foreach($cr as $k=>&$v){
$v['a1'] = $v['a1'] - 1;
$v['a2'] = $v['a2'] - 1;
$v['a3'] = $v['a3'] - 1;
$v['a4'] = $v['a4'] - 1;
$v['a5'] = $v['a5'] - 1;
}
print_r($cr);

Global array in php issues

I've found some very helpful answers but still have some problems.
I want to put different rows in global array, WITHOUT removing the other rows.
<?php
global $global_arr;
function first() {
///some code
global $global_arr;
$global_arr[] = array('first' =>
array('1' , '1', '1'));
}
function second() {
///some code
global $global_arr;
$global_arr[] = array('second' =>
array('2' , '2', '2'));
}
function third() {
///some code
global $global_arr;
$global_arr[] = array('third' =>
array('3' , '3', '3'));
}
first();
second();
third();
print_r($global_arr);
I want every of the functions to index the array and add rows respectevly
Thank you in advance!
Edit :
Thank to your help here is the working version :
function first($arr) {
$arr[] = array('first' =>
array(1, 1, 1));
return $arr;
}
function second($arr) {
$arr[] = array('second' =>
array(2, 2, 2));
return $arr;
}
$arr = array();
$arr = first($arr);
$arr = second($arr);
print_r($arr);
Output :
Array ( [0] => Array ( [first] => Array ( [0] => 1 [1] => 1 [2] => 1 ) ) [1] => Array ( [second] => Array ( [0] => 2 [1] => 2 [2] => 2 ) ) )
Any ideas how to be only :
Array ( [first] => Array ( [0] => 1 [1] => 1 [2] => 1) , [second] => Array([0] => 2, [1] => 2, [2] => 2))
?
$global_arr['third'][] = array('3.1' , '3.2', '3.3');
I don't get it - it's the same in/for all three functions.
BTW, I would use only one function like:
<?php
// $arg1 = "one", "two" or "three"
// $arg2 = ARRAY("data1.1", "data1.2", "data1.3") {
function myfunc($arg1, $arg2) {
if (!isset($my_arr)) { static $my_arr = ARRAY(); }
$my_arr[$arg1][] = $arg2;
return $my_arr; // Or code a getter and setter function
}
// Call, as often as you want - like:
myfunc('one', ARRAY('1.1', '1.2','1.3'));
myfunc('two', ARRAY('2.1', '2.2','2.3'));
$arr = myfunc('one', ARRAY('1.4', '1.5','1.6'));
print '<pre>';
var_dump($arr);
print '</pre>';
/* result:
array(2) {
["one"]=>
array(2) {
[0]=>
array(3) {
[0]=>
string(3) "1.1"
[1]=>
string(3) "1.2"
[2]=>
string(3) "1.3"
}
[1]=>
array(3) {
[0]=>
string(3) "1.4"
[1]=>
string(3) "1.5"
[2]=>
string(3) "1.6"
}
}
["two"]=>
array(1) {
[0]=>
array(3) {
[0]=>
string(3) "2.1"
[1]=>
string(3) "2.2"
[2]=>
string(3) "2.3"
}
}
}
*/
?>
Why you want to use global variable? You can simply write
function first($arr) {
$arr[] = array('first' =>
array('3' , '3', '3'));
return $arr;
}
function second($arr) {
$arr[] = array('second' =>
array('3' , '3', '3'));
return $arr;
}
function third($arr) {
$arr[] = array('third' =>
array('3' , '3', '3'));
return $arr;
}
$arr = array();
$arr = first($arr);
$arr = second($arr);
$arr = third($arr);

Categories