Add value to existing array key in foreach loop - php

I have the following bibliography data in an array (note that fields are in random order - there are others fields as well):
Array
(
[0] => Array
(
['Pub_Name'] => Nature
['Volume'] => 6
['Pages'] => 215-217
)
[1] => Array
(
['Volume'] => 15
['Pages'] => 358-360
['Pub_Name'] => Science
)
[2] => Array
(
['Pub_Name'] => PNAS
['Pages'] => 17-19
['Volume'] => 22
)
)
I want to "merge" those three fields into one, for example ['Pub_Name']=Nature, 6: 215-217. I tried the following whitout success (I guess $Record['Pub_Name'] is the incorrect sintax):
foreach ($MyArray as $Record) {
foreach ($Record as $key => $values) {
if ($key=="Volume") {$Volumen=", ".$values;} else {$Volumen="";}
if ($key=="Pages") {$Paginas=": ".$values;} else {$Paginas="";}
}
//This is the line for which I want to know the sintax!!
$Record['Pub_Name'].=$Volumen.$Paginas;
}

No need for two loops:
foreach ($MyArray as $Record) {
$result[]['Pub_Name'] = "{$Record['Pub_Name']}, {$Record['Pages']}: {$Record['Volume']}";
}
Then you have the new Pub_Name entries in $result.
If you want to modify the original then reference & $Record:
foreach ($MyArray as &$Record) {
$Record['Pub_Name'] = "{$Record['Pub_Name']}, {$Record['Pages']}: {$Record['Volume']}";
}
Or use the key and modify the original array:
foreach ($MyArray as $key => $Record) {
$MyArray[$key]['Pub_Name'] = "{$Record['Pub_Name']}, {$Record['Pages']}: {$Record['Volume']}";
}

PHP code demo
<?php
$array=Array
(
0 => Array
(
'Pub_Name' => "Nature",
'Volume' => 6,
'Pages' => "215-217"
),
1 => Array
(
'Volume' => 15,
'Pages' => "358-360",
'Pub_Name' => "Science"
),
2 => Array
(
'Pub_Name' => 'PNAS',
'Pages' => "17-19",
'Volume' => 22
)
);
$result=array();
foreach ($array as $data)
{
$result[]=array('Pub_Name'=> $data['Pub_Name'].", ".$data["Volume"].": ".$data["Pages"]);
}
print_r($result);
Output:
Array
(
[0] => Array
(
[Pub_Name] => Nature, 6: 215-217
)
[1] => Array
(
[Pub_Name] => Science, 15: 358-360
)
[2] => Array
(
[Pub_Name] => PNAS, 22: 17-19
)
)

I guess this is what you are looking for:
<?php
$input = [
[
'Pub_Name' => 'Nature',
'Volume' => '6',
'Pages' => '215-217'
],
[
'Volume' => '15',
'Pages' => '358-30',
'Pub_Name' => 'Science',
],
[
'Pub_Name' => 'PNAS',
'Pages' => '17-19',
'Volume' => '22'
]
];
$output = [];
array_walk($input, function ($entry) use (&$output) {
$output[] = sprintf(
'%s, %s: %s',
$entry['Pub_Name'],
$entry['Volume'],
$entry['Pages']
);
});
print_r($output);
The output of above code obviously is:
Array
(
[0] => Nature, 6: 215-217
[1] => Science, 15: 358-30
[2] => PNAS, 22: 17-19
)

Use array_map
$in = [
0 => [
'Pub_Name' => 'Nature',
'Volume' => 6,
'Pages' => '215-217'
],
1 => [
'Volume' => 15,
'Pages' => '358-360',
'Pub_Name' => 'Science',
],
2 => [
'Pub_Name' => 'PNAS',
'Pages' => '17-19',
'Volume' => 22
]
];
array_map(function ($item) {
return $item['Pub_Name'] . ', ' . $item['Volume'] . ': ' . $item['Pages'];
}, $in);

There are a few different ways to do this - but one of the more readable ways:
// create a copy of the original - so we aren't looping thru the same array we're updating
$updatedArray = $MyArray;
foreach ($MyArray as $index => $record) {
$updatedArray[$index]['Pub_Name'] =
$record['Pub_Name'].
($record['Volume'] ? ', '.$record['Volume'] : '').
($record['Pages'] ? ': '.$record['Pages']:'');
}

Clear way in a single loop. Use sprintf() for easy formatting:
<?php
$src =[ ['Pub_Name' => 'Nature', 'Volume' => '6', 'Pages' => '215-217'],
['Volume' => '15', 'Pages' => '358-30', 'Pub_Name' => 'Science'],
['Pub_Name' => 'PNAS', 'Pages' => '17-19', 'Volume' => '22']
];
foreach ($src as $element) {
$dest[] = sprintf("%s, %d: %s",
$element['Pub_Name'],
$element['Volume'],
$element['Pages']);
}
var_dump($dest);
?>
And you get:
array(3) {
[0]=> string(18) "Nature, 6: 215-217"
[1]=> string(19) "Science, 15: 358-30"
[2]=> string(15) "PNAS, 22: 17-19"
}
Test it here.

This should help:
$combined = [];
foreach($myArray as $pub) {
$combined.push($pub['Pub_Name'] . ', ' . $pub['Volume'] . ': ' . $pub['Pages']);
}

Related

PHP only remove commas from numbers in this associative array?

What is the best method to remove commas from numbers in the associative array below? Keep the commas in text, thanks.
$main_arr contains the following 3 arrays:
Array
(
[phrase] => Hi, I'm ok
[number_a] => 3,575
[number_b] => 64
[number_c] => 8,075
)
Array
(
[phrase] => Bye, it's late
[number_a] => 7,365
[number_b] => 32
[number_c] => 648,120
)
Array
(
[phrase] => Good catch!
[number_a] => 11,659
[number_b] => 128
[number_c] => 1,492,352
<?php
$mainArray =[
[
'phrase' => "Hi, I'm ok",
'number_a' => "3,575",
'number_b' => "64",
'number_c' => "8,075",
],
[
'phrase' => "Bye, it's late",
'number_a' => "7,365",
'number_b' => "32",
'number_c' => "648,120",
],
[
'phrase' => 'Good catch!',
'number_a' => "11,659",
'number_b' => "128",
'number_c' => "1,492,352",
],
];
foreach($mainArray as &$array) {
foreach($array as &$val) {
if (preg_match('/^[0-9,]*$/', $val)){
$val = str_replace(',','',$val);
}
}
}
var_export($mainArray);

arrays with dif keys inside 1 array

like the question says, I have 2 foreach cycles, 1 cycle iterates an array with 4 keys, and the other one an array with 3 keys, how to get this two arrays in only 1 ?
I have this
....
],
],
'Detalle' => array()
];
foreach ($datos["line_items"] as $line => $item) {
$tempArray = array(
'NmbItem' => $item['name'],
'QtyItem' => $item['quantity'],
'PrcItem' => $item['price'],
'IndExe' => 1
);
}
foreach($datos["fee_lines"] as $line => $fee){
$tempArray=array(
'NmbItem' => $fee['name'],
'QtyItem' => 1,
'PrcItem' => $fee['total']
);
}
$dte['Detalle'][] = $tempArray;
}
if you notice the second array cycle doesnt contain 'indexe' key, after asign this tempArray in $dte['Detalle'][] = $tempArray only works with the last cycle, or the first one if I remove the second.
the output should be something like:
temp = Array (
array[0]
'NmbItem => name',
'QtyItem'=> 10,
'PrcItem'= 1000,
'IndExe' => 1
array[1]
'NmbItem => another name',
'QtyItem'=> 5,
'PrcItem'=> 3000
)
To make it work with your code, you should also add $dte['Detalle'][] = $tempArray; after the first loop.
The issue is that you are setting the $tempArray in each foreach so you end up with only the last one when assigning it in the $dte['Detalle'].
So, something like this should work:
foreach ($datos["line_items"] as $line => $item) {
$tempArray = array(
'NmbItem' => $item['name'],
'QtyItem' => $item['quantity'],
'PrcItem' => $item['price'],
'IndExe' => 1
);
}
$dte['Detalle'][] = $tempArray;
foreach($datos["fee_lines"] as $line => $fee){
$tempArray=array(
'NmbItem' => $fee['name'],
'QtyItem' => 1,
'PrcItem' => $fee['total']
);
}
$dte['Detalle'][] = $tempArray;
However, I would do it using the array_map function.
Docs for array_map
You can have it something like this:
<?php
$data_1 = array_map(function($item){
return array(
'NmbItem' => $item['name'],
'QtyItem' => $item['quantity'],
'PrcItem' => $item['price'],
'IndExe' => 1
);
}, $datos["line_items"]);
$data_2 = array_map(function($fee){
return array(
'NmbItem' => $fee['name'],
'QtyItem' => 1,
'PrcItem' => $fee['total']
)
}, $datos["fee_lines"]);
$dte['Detalle'] = array_merge($dte['Detalle'], $data_1, $data_2);

Writing a HTML string content with array values in Laravel Controller

What I'm trying to accomplish is to write a html string in a controller with array values being looped in it. So for example;
$content = "Your store, at location A, has these items added to them". add array loop here. "Do take note!";
My array would be as such
array (
0 =>
array (
'id' => '5db29b6d31c391731239bbdf',
'name' => 'Diamond bracelet (sample)',
'tags' =>
array (
0 => 'female',
1 => 'jewelry',
),
'category' => 'Accessories',
'sku' => '1029EHW',
'priceType' => 'Fixed',
'unitPrice' => 190,
'cost' => 90,
'trackStockLevel' => true,
'isParentProduct' => false,
),
1 =>
array (
'id' => '5db29b6d31c391731239bbdb',
'name' => 'Long-sleeved shirt(sample)(M)',
'tags' =>
array (
0 => 'tops',
1 => 'cotton',
),
'category' => 'Women\'s Apparel',
'sku' => 'ABC1234-M',
'priceType' => 'Fixed',
'unitPrice' => 47.170000000000002,
'cost' => 20,
'trackStockLevel' => true,
'isParentProduct' => false,
'parentProductId' => '5db29b6d31c391731239bbd4',
'variationValues' =>
array (
0 =>
array (
'variantGroupId' => '5db29b6d31c391731239bbd5',
'value' => 'M',
),
),
),
)
note that the array can have many instances of product_name and sku, or can have none.
How do i populate this in my string to be like;
$content = "Your store, at location A, has these items added to them, 1) asd, 2)def, 3)asf . Do take note!
Try this, I've used \sprintf for ease, check if the output serves your purpose.
<?php
function stringMethod(): string
{
$count = 0;
$arrayString = [];
$array = [['product_name' => 'abc', 'product_sku' => 'def'],['product_name' => 'abc', 'product_sku' => 'asd']];
foreach ($array as $value){
$count++;
$arrayString[] = sprintf('%s)%s', $count, $value['product_sku']);
}
$string = \implode(',', $arrayString);
return \sprintf("Your store, at location A, has these items added to them %s Do take note!", $string);
}
echo stringMethod();
Hope this will help you. try to do it in less number of lines
$content = "Your store, at location A, has these items added to them, ";
$productArray = array (0 => array ('id' => '5db29b6d31c391731239bbdf','name' => 'Diamond bracelet (sample)','tags' => array (0 => 'female',1 => 'jewelry',),'category' => 'Accessories','sku' => '1029EHW','priceType' => 'Fixed','unitPrice' => 190,'cost' => 90,'trackStockLevel' => true,'isParentProduct' => false,),1 => array ('id' => '5db29b6d31c391731239bbdb','name' => 'Long-sleeved shirt(sample)(M)','tags' => array (0 => 'tops',1 => 'cotton',),'category' => 'Women\'s Apparel','sku' => 'ABC1234-M','priceType' => 'Fixed','unitPrice' => 47.170000000000002,'cost' => 20,'trackStockLevel' => true,'isParentProduct' => false,'parentProductId' => '5db29b6d31c391731239bbd4','variationValues' => array (0 => array ('variantGroupId' => '5db29b6d31c391731239bbd5','value' => 'M'))));
foreach ($productArray as $key => $product) {
$content .= ($key+1).') '.$product['name'];
if (count($productArray)-1!=$key) {
$content .= ', ';
}
}
$content .= ". Do take note!";
$content = "Your store, at location A, has these items added to them,". $this->getItemList($collection) .". Do take note!"
# Somewhere else in the controller
protected function getItemList(Collection $collection): string
{
return $collection->pluck('name')
->merge($collection->pluck('sku'))
->map(function($item, $key) {
return ($key + 1) . ') ' . $item;
})
->implode(', ');
}
An easy solution would be
$content = "Your store, at location A, has these items added to them";
$array = array(0=>["product_name" => "abc", "product_sku" => "def"], 1=>['product_name' => 'kdkf', 'product_sku'=> 'ljbkj']);
for($i = 0; $i<count($array); $i++){
$content .= ($i+1).") ".$array[$i]['product_name].' '.$array[$i]['product_sku'].', ';
}
$content .= "Do take note.";
This way you're just constantly concatonating the string value in separate parts instead of trying to inject it in the middle of the parent string.
not tested, may be syntax errors

Compare element in array and loop through each php

I want to compare a value of data to a list of element which I had retrieved from php array(decoded json).
First,
This is the first array:
Array1
(
[0] => Array
(
[member_id] => 3
[member_card_num] => 2013011192330791
[member_barcode] => 2300067628912
)
[1] => Array
(
[member_id] => 4
[member_card_num] => 2328482492740000
[member_barcode] => 3545637000
)
[2] => Array
(
[member_id] => 2
[member_card_num] => 40001974318
[member_barcode] => 486126
)
[3] => Array
(
[member_id] => 1
[member_card_num] => 91001310000057698
[member_barcode] => 000057698
)
)
This is the second Array:
Array2
(
[0] => Array
(
[member_id] => 2
[member_card_num] => 40001974318
[member_barcode] => 486126
)
)
Second,
I had retrieved the (member_barcode) which I required.
Here is the code:
For Array1:
foreach ($decode1 as $d){
$merchant_barcode = $d ['member_barcode'];
echo $merchant_barcode;
}
For Array2:
foreach ($decode2 as $d2){
$user_barcode = $d2 ['member_barcode'];
echo $user_barcode;
}
Then,
I get this output():
For Array1(merchant_barcode):
2300067628912
3545637000
486126
000057698
For Array2(user_barcode):
486126
The question is, I would to check and compare whether the user_barcode in Array2(486126) is exist/match to one of the merchant_barcode in Array1.
This is my code,
but it only compare the user_barcode in Array2 to the last element(000057698) in Array1,
I want it to loop through each n check one by one. How can I do that?
public function actionCompareBarcode($user_barcode, $merchant_barcode){
if(($user_barcode) == ($merchant_barcode)){
echo "barcode exist. ";
}
else{
echo "barcode not exist";
}
}
In this case, the output I get is "barcode not exist", but it should be "barcode exist".
Anyone can help? Appreciate that. Im kinda new to php.
You could use a nested loop like:
foreach ($decode2 as $d2)
{
$user_barcode = $d2 ['member_barcode'];
foreach ($decode1 as $d)
{
$merchant_barcode = $d ['member_barcode'];
if ($merchant_barcode == $user_barcode)
{
echo "Match found!";
}
else
{
echo "No match found!";
}
}
}
<?
$a = array(
array(
'member_id' => 3,
'member_card_num' => '2013011192330791',
'member_barcode' => '2300067628912',
),
array(
'member_id' => 4,
'member_card_num' => '2328482492740000',
'member_barcode' => '3545637000',
),
array(
'member_id' => 2,
'member_card_num' => '40001974318',
'member_barcode' => '486126',
),
array(
'member_id' => 1,
'member_card_num' => '91001310000057698',
'member_barcode' => '000057698',
)
);
$b = array(
array(
'member_id' => 2,
'member_card_num' => '40001974318',
'member_barcode' => '486126',
)
);
array_walk($a, function($item) use($b) {
echo ($b['0']['member_barcode'] == $item['member_barcode'] ? "found" : NULL);
});
?>
I'd use array_uintersect() to calculate if those multidimensional arrays have a common element:
<?php
$a = array(
array(
'member_id' => '3',
'member_card_num' => '2013011192330791',
'member_barcode' => '2300067628912',
),
array(
'member_id' => '2',
'member_card_num' => '40001974318',
'member_barcode' => '486126',
)
);
$b = array(
array(
'member_id' => '2',
'member_card_num' => '40001974318',
'member_barcode' => '486126',
)
);
$match = array_uintersect($a, $b, function($valueA, $valueB) {
return strcasecmp($valueA['member_barcode'], $valueB['member_barcode']);
});
print_r($match);
Try calling that method as you are looping through Array1 and comparing the user_barcode to every value
You can compare two array this way too:
$per_arr = array();
$permissions = array()
foreach ($per_arr as $key => $perms) {
if(isset($permissions[$key]['name'])){
echo $per_arr[$key]['name']; //matched data
}else{
echo $per_arr[$key]['name']; //not matched data
}
}

how to find a element in a nested array and get its sub array index

when searching an element in a nested array, could i get back it's 1st level nesting index.
<?php
static $cnt = 0;
$name = 'victor';
$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, $search_query){
global $cnt;
if($v == $search_query){
/* i want the sub array index to be returned */
}
}
?>
i.e to say, if i'am searching 'victor', i would like to have 'dep1' as the return value.
Could anyone help ??
Try:
$name = 'victor';
$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')
)
);
$iter = new RecursiveIteratorIterator(new RecursiveArrayIterator($coll), RecursiveIteratorIterator::SELF_FIRST);
/* These will be used to keep a record of the
current parent element it's accessing the childs of */
$parent_index = 0;
$parent = '';
$parent_keys = array_keys($coll); //getting the first level keys like dep1,dep2
$size = sizeof($parent_keys);
$flag=0; //to check if value has been found
foreach ($iter as $k=>$val) {
//if dep1 matches, record it until it shifts to dep2
if($k === $parent_keys[$parent_index]){
$parent = $k;
//making sure the counter is not incremented
//more than the number of elements present
($parent_index<$size-1)?$parent_index++:'';
}
if ($val == $name) {
//if the value is found, set flag and break the loop
$flag = 1;
break;
}
}
($flag==0)?$parent='':''; //this means the search string could not be found
echo 'Key = '.$parent;
Demo
This works , but I don't know if you are ok with this...
<?php
$name = 'linda';
$col1=array ( 'dep1' => array ( 'fy' => array ( 0 => 'john', 1 => 'johnny', 2 => 'victor', ), 'sy' => array ( 0 => 'david', 1 => 'arthur', ), 'ty' => array ( 0 => 'sam', 1 => 'joe', 2 => 'victor', ), ), 'dep2' => array ( 'fy' => array ( 0 => 'natalie', 1 => 'linda', 2 => 'molly', ), 'sy' => array ( 0 => 'katie', 1 => 'helen', 2 => 'sam', 3 => 'ravi', 4 => 'vipul', ), 'ty' => array ( 0 => 'sharon', 1 => 'julia', 2 => 'maddy', ), ), );
foreach($col2 as $k=>$arr)
{
foreach($arr as $k1=>$arr2)
{
if(in_array($name,$arr2))
{
echo $k;
break;
}
}
}
OUTPUT :
dept2
Demo

Categories