Group values in multi-dimensional array based on a key - php

I have the following multi-dimensional array:
Array
(
[0] => Array
(
[sname] => florida
[cname] => orlando
)
[1] => Array
(
[sname] => texas
[cname] => dallas
)
[2] => Array
(
[sname] => florida
[cname] => tampa
)
[3] => Array
(
[sname] => ohio
[cname] => columbus
)
)
How would I go about trying to get all 'cname' values associated with each 'sname' value?
florida: orlando, tampa
texas: dallas
ohio: columbus

There are probably several ways to do this. The one that comes to mind is something like this:
<?php
$payload = [];
$origin = [
[
'sname' => 'florida',
'cname' => 'orlando'
],
[
'sname' => 'texas',
'cname' => 'dallas'
],
[
'sname' => 'florida',
'cname' => 'tampa'
],
[
'sname' => 'ohio',
'cname' => 'columbus'
]
];
foreach ($origin as $value) {
if (! isset($payload[$value['sname']])) {
$payload[$value['sname']] = '';
}
$payload[$value['sname']] .= (strlen($payload[$value['sname']]) >0?',':'') . $value['cname'];
}
print_r($payload);
Cheers! :)
=C=

With a slight tweak of Mike's solution (https://stackoverflow.com/a/2189916/4954574), the following will produce what I was hoping for:
$input_arr = array(
array("sname" => "florida", "cname" => "orlando"),
array("sname" => "texas", "cname" => "dallas"),
array("sname" => "florida", "cname" => "tampa"),
array("sname" => "ohio", "cname" => "columbus")
);
foreach ($input_arr as $key => &$entry) {
$level_arr[$entry['sname']][$key] = $entry['cname'];
}
print_r($level_arr);
Output:
Array
(
[florida] => Array
(
[0] => orlando
[2] => tampa
)
[texas] => Array
(
[1] => dallas
)
[ohio] => Array
(
[3] => columbus
)
)

Related

PHP arrays combine values of the right key

I have a question about arrays in PHP:
I have many zip files having many data inside and using preg_grep I could get the results below:
(These data are returned from multiple text files in the zip file)
=> Array
(
[ZipName] => data.zip
[Age] => 45
)
=> Array
(
[ZipName] => data.zip
[Name] => John
)
=> Array
(
[ZipName] => data2.zip
)
=> Array
(
[ZipName] => data1.zip
[Age] => 25
)
=> Array
(
[ZipName] => data2.zip
[Age] => 27
)
=> Array
(
[ZipName] => data1.zip
[Name] => Abram
)
=> Array
(
[ZipName] => data1.zip
)
=> Array
(
[ZipName] => data2.zip
[City] => London
)
=> Array
(
[ZipName] => data2.zip
[Name] => Inna
)
=> Array
(
[ZipName] => data1.zip
[City] => London
)
So how I can combine/merge all of these arrays using the ZipName Value !
Like in SQL it easy :
SELECT * FROM * WHERE ZipName= 'x';
0 => Array
(
[ZipName] => data.zip
[Age] => 45
[Name] => John
[City] => Leicester
)
1 => Array
(
[ZipName] => data1.zip
[Age] => 25
[Name] => Abram
[City] => London
)
2 => Array
(
[ZipName] => data2.zip
[Age] => 27
[Name] => Inna
[City] => London
)
An alternative to using array_merge, array_combine etc.. ...is just two simple foreach loops and setting the value into a new array ($new_arr).
$new_arr = [];
foreach($arr as $inner_arr) {
foreach($inner_arr as $key=>$value) {
$new_arr[$key] = $value;
}
}
UPDATE
I was not clear what OP wanted but I hope it's clearer now:
Try this:
(Basically adding values to array[name of ZipName][{current key for the inner array}]
$arr = [
[
'ZipName' => 'data.zip',
'Age' => '45'
],
[
'ZipName' => 'data.zip',
'Name' => 'John'
],
[
'ZipName' => 'data2.zip',
'Age' => '27'
],
[
'ZipName' => 'data1.zip',
'Name' => 'Abram'
],
[
'ZipName' => 'data1.zip'
],
[
'ZipName' => 'data2.zip',
'City' => 'London'
],
[
'ZipName' => 'data2.zip',
'Name' => 'Inna'
],
[
'ZipName' => 'data1.zip',
'City' => 'London'
]
];
$new_arr = [];
foreach($arr as $key => $inner_arr) {
foreach($inner_arr as $ik => $item) {
$new_arr[$inner_arr['ZipName']][$ik] = $item;
}
}
Output:
Array
(
[data.zip] => Array
(
[ZipName] => data.zip
[Age] => 45
[Name] => John
)
[data2.zip] => Array
(
[ZipName] => data2.zip
[Age] => 27
[City] => London
[Name] => Inna
)
[data1.zip] => Array
(
[ZipName] => data1.zip
[Name] => Abram
[City] => London
)
)
When doing:
$new_arr = array_values($new_arr);
the key simply gets do be a numeric index (if it matters)
Array
(
[0] => Array
(
[ZipName] => data.zip
[Age] => 45
[Name] => John
)
[1] => Array
(
[ZipName] => data2.zip
[Age] => 27
[City] => London
[Name] => Inna
)
[2] => Array
(
[ZipName] => data1.zip
[Name] => Abram
[City] => London
)
)
What you need is to group by the unique values at the index ['ZipName'] and then merge those groups individually. This can be done with array_reduce.
Example:
<?php
declare(strict_types=1);
$input = [
[
'ZipName' => 'data_1.zip',
'Age' => 45,
], [
'ZipName' => 'data_1.zip',
'Name' => 'John',
], [
'ZipName' => 'data_1.zip',
], [
'ZipName' => 'data_1.zip',
'City' => 'Leicester',
],
[
'ZipName' => 'data_2.zip',
'Age' => 45,
], [
'ZipName' => 'data_2.zip',
'Name' => 'John',
], [
'ZipName' => 'data_2.zip',
], [
'ZipName' => 'data_2.zip',
'City' => 'Leicester',
],
];
$output = array_values(array_reduce($input, static function (array $acc, array $item): array {
$acc[$item['ZipName']] = array_merge($acc[$item['ZipName']] ?? [], $item);
return $acc;
}, []));
print_r($output);
I think you are going to combine different arrays, So please use array merge.
$array0 = Array
(
"ZipName" => data.zip,
"Age" => 45
);
$array1 = Array
(
"ZipName" => data.zip,
"Name" => John
);
$array2 = Array
(
"ZipName" => data.zip
);
$array3 = Array
(
"ZipName" => data.zip,
"City" => Leicester
);
print_r(array_merge($array0, $array1, $array2, $array3));
Out Put:
Array ( [ZipName] => datazip
[Age] => 45
[Name] => John
[City] => Leicester )

Forming final array with multiple array in PHP [duplicate]

This question already has answers here:
How to find array / dictionary value using key?
(2 answers)
Closed 3 years ago.
I need to form the final array, its not displaying how i am expecting, here is the code i used.
I need to print the final array in the expected format, I have attached the output how i am looking for in the below section,
<?php
$order_id = 12345;
$array1 = array(
"firstName" => "Test Fname",
"lastName" => "Test Lname",
"address1" => "Test Address",
"city" => "Test City",
"country" => "IND",
"email" => "test#blank.in"
);
$array2 = array(
"firstName" => "Test Fname",
"lastName" => "Test Lname",
"address1" => "Test Address",
"city" => "Test City",
"country" => "IND",
"email" => "test#blank.in"
);
$result = array("user_id" =>"9999","item_id" =>"cloth","price" =>"500","qty" =>"100");
$itemDetails = array();
foreach($result as $res){
$itemDetails[] =
array(
"User" => array(
"uservalue" => $res['user_id'],
"imageId" => $res['item_id']
),
"price" => $res['price'],
"qty" => $res['qty']
);
}
$final_array = array(
"id" => $order_id,
"billing" => $array1,
"shipping" => $array2,
"item" => $itemDetails
);
echo '<pre>';
print_r($final_array);die;
?>
Output of current Code
Array
(
[id] => 12345
[billing] => Array
(
[firstName] => Test Fname
[lastName] => Test Lname
[address1] => Test Address
[city] => Test City
[country] => IND
[email] => test#blank.in
)
[shipping] => Array
(
[firstName] => Test Fname
[lastName] => Test Lname
[address1] => Test Address
[city] => Test City
[country] => IND
[email] => test#blank.in
)
[item] => Array
(
[0] => Array
(
[User] => Array
(
[uservalue] => 9999
[imageId] => cloth
)
[price] => 500
[qty] => 100
)
[1] => Array
(
[User] => Array
(
[uservalue] => 9999
[imageId] => cloth
)
[price] => 500
[qty] => 100
)
[2] => Array
(
[User] => Array
(
[uservalue] => 9999
[imageId] => cloth
)
[price] => 500
[qty] => 100
)
)
)
Expected Result should be like below
array
(
"id" => 12345
"billing" => array
(
[firstName] => Test Fname,
[lastName] => Test Lname,
[address1] => Test Address,
[city] => Test City,
[country] => IND,
[email] => test#blank.in
)
"shipping" => array
(
[firstName] => Test Fname,
[lastName] => Test Lname,
[address1] => Test Address,
[city] => Test City,
[country] => IND,
[email] => test#blank.in
)
"item" => array
(
array
(
"User" => Array
(
"uservalue" => 9999,
"imageId" => cloth
)
[price] => 500,
[qty] => 100
)
)
)
I am expecting output like above, can we display the final array in that format, can anyone look into it and update me your thoughts. Thanks!!
if you allow only single item in itemdetails
$itemDetails[] =
[
"User" => [
"uservalue" => $result['user_id'],
"imageId" => $result['item_id'],
],
"price" => $result['price'],
"qty" => $result['qty'],
];
Single item demo
if itemdetails allow multiple items
$result = [
["user_id" =>"9999","item_id" =>"cloth","price" =>"500","qty" =>"100"],
["user_id" =>"9999","item_id" =>"cloth","price" =>"400","qty" =>"200"]
];
$itemDetails = array();
foreach($result as $res){
$itemDetails[] =
array(
"User" => array(
"uservalue" => $res['user_id'],
"imageId" => $res['item_id']
),
"price" => $res['price'],
"qty" => $res['qty']
);
}
Multiple items demo
If $result has multiple values, this should work.
$result = array(array("user_id" =>"9999","item_id" =>"cloth","price" =>"500","qty" =>"100"),array("user_id" =>"500","item_id" =>"cloth123","price" =>"511","qty" =>"80"));
$itemDetails = array();
foreach($result as $res){
$itemDetails[] =
array(
"User" => array(
"uservalue" => $res['user_id'],
"imageId" => $res['item_id']
),
"price" => $res['price'],
"qty" => $res['qty']
);
}
$final_array = array(
// "id" => $order_id,
// "billing" => $array1,
// "shipping" => $array2,
"item" => $itemDetails
);
echo '<pre>';
print_r($final_array);
Output
Array
(
[item] => Array
(
[0] => Array
(
[User] => Array
(
[uservalue] => 9999
[imageId] => cloth
)
[price] => 500
[qty] => 100
)
[1] => Array
(
[User] => Array
(
[uservalue] => 500
[imageId] => cloth123
)
[price] => 511
[qty] => 80
)
)
)

Php check and replace if value exist in multi array?

Problem:
I dont know/understand how to check if date and place exists on the same "row" and they exists more then once.
Second, how do i then merge an array
my case MergeArray with ArraySchedule
Code:
$ArraySchedule = array();
while ($data = $stmt -> fetch(PDO::FETCH_ASSOC)) {
$schedules = array(
"id" => $data['id'],
"name" => $data['name'],
"date" => $data['date'],
"time" => $data['time'],
"place_id" => $data['place_id'],
"place" => $data['place'],
);
array_push($ArraySchedule, $schedules);
}
$dupe_array = array();
foreach ($ArraySchedule as $key => $value) {
if(++$dupe_array[$value["date"]] > 1 && ++$dupe_array[$value["place_id"]] > 1 ){
// this statement is wrong, i want something like:
// if date and place_id exists on the same "row" and they exists more then once
}
}
What i want to do:
Check if ArraySchedule contains schedules that have the same date and place,
if there is more than one schedule that has the same date and place_id.
then I want to update ArraySchedule with this structure
$MergeArray = array(
"id" => ArraySchedule['id'],
"name" => array(
"name" => scheduleSameDateAndPlace['name'],
"name" => scheduleSameDateAndPlace['name'],
"name" => scheduleSameDateAndPlace['name'],
),
"date" => $ArraySchedule['date'],
"time" => $ArraySchedule['time'],
"place_id" => $ArraySchedule['place_id'],
"place_name" => $ArraySchedule['place_name'],
),
MergeArray with ArraySchedule?
anyway...
Output I think I want?
Print_r($ArraySchedule)
array(
[0] =>
array(
[id] => 1
[names] => Simon
[date] => 2019-01-02
[time] 18.00
[place_id] => Tystberga Park
[place] => Tystberga
)
[1] =>
array(
[id] => 2
//[names] insted of [name]?
[names] =>
array(
[name] => Vincent
[name] => Angel
[name] => Kim
)
[date] => 2019-02-17
[time] => 13.00
[place_id] => Borås Park
[place] => Borås
)
[2] =>
array(
[id] => 3
// [names] is always an array?
[names] => Caitlyn
[date] => 2019-03-15
[time] 13.00
[place_id] => Plaza Park
[place] => EvPark
)
)
You can use array-reduce. Consider the following:
function mergeByDateAndPlace($carry, $item) {
$key = $item["place_id"] . $item["date"]; // creating key matching exact place and date
if (!isset($carry[$key])) {
$carry[$key]["name"] = $item["name"];
} else {
$carry[$key] = $item;
$item["name"] = [$item["name"]]; // make default array with 1 element so later can be append other names
}
return $carry;
}
Now use it with:
$MergeArray = array_reduce($ArraySchedule, "mergeByDateAndPlace", []);
If you later want to know if there were any duplicate you can just loop on $MergeArray. You can also use array_values if you want to discard the concat keys.
Notice #Nick 2 important comment about saving the first loop and the "time" value that need to be decided. Also notice your desire output contain multi element with the same key ("name") - you need to append them with int key - Array can not have duplicate keys.
Hope that helps!
Here is my data from my database:
var_export($ArraySchedule)
array (
0 => array ( 'id' => '225', 'place_id' => 'Alviks Kulturhus', 'name' => 'BarraBazz', 'date' => '2019-03-19', 'placeadress' => 'Gustavslundsvägen 1', ),
1 => array ( 'id' => '229', 'place_id' => 'Axelhuset Göteborg', 'name' => 'Anders Björk', 'date' => '2019-04-08', 'placeadress' => 'Axel Dahlströms torg 3', ),
2 => array ( 'id' => '230', 'place_id' => 'Axelhuset Göteborg', 'name' => 'Black Jack', 'date' => '2019-04-08', 'placeadress' => 'Axel Dahlströms torg 3', ),
3 => array ( 'id' => '227', 'place_id' => 'Arosdansen Syrianska Kulturcentret', 'name' => 'BarraBazz', 'date' => '2019-05-08', 'placeadress' => 'Narvavägen 90', ),
4 => array ( 'id' => '228', 'place_id' => 'Aspåsnäset', 'name' => 'Blender', 'date' => '2019-05-25', 'placeadress' => 'Aspåsnäset 167', ),
5 => array ( 'id' => '226', 'place_id' => 'Arenan Västervik Resort', 'name' => 'Blender', 'date' => '2019-06-29', 'placeadress' => 'Lysingsvägen', ),
6 => array ( 'id' => '222', 'place_id' => 'Alingsåsparken', 'name' => 'Bendéns', 'date' => '2019-07-16', 'placeadress' => 'Folkparksgatan 3A', ),
7 => array ( 'id' => '223', 'place_id' => 'Alingsåsparken', 'name' => 'Charlies', 'date' => '2019-07-16', 'placeadress' => 'Folkparksgatan 3A', ),
8 => array ( 'id' => '224', 'place_id' => 'Allhuset Södertälje', 'name' => 'Cedrix', 'date' => '2019-07-16', 'placeadress' => 'Barrtorpsvägen 1A', ), )
I want to update the "name" with an array of names everytime that place_id and date are the same.
This is the output I want:
Array (
[0] =>
Array ( [id] => 225 [place_id] => Alviks Kulturhus [name] => BarraBazz [date] => 2019-03-19 [placeadress] => Gustavslundsvägen 1 )
[1] =>
Array ( [id] => 229 [place_id] => Axelhuset Göteborg [name] => Array([0] => Anders Björk [1] => Black Jack ) [date] => 2019-04-08 [placeadress] => Axel Dahlströms torg 3 )
[3] =>
Array ( [id] => 227 [place_id] => Arosdansen Syrianska Kulturcentret [name] => BarraBazz [date] => 2019-05-08 [placeadress] => Narvavägen 90 )
[4] =>
Array ( [id] => 228 [place_id] => Aspåsnäset [name] => Blender [date] => 2019-05-25 [placeadress] => Aspåsnäset 167 )
[5] =>
Array ( [id] => 226 [place_id] => Arenan Västervik Resort [name] => Blender [date] => 2019-06-29 [placeadress] => Lysingsvägen )
[6] =>
Array ( [id] => 222 [place_id] => [Alingsåsparken] [name] => Array([0] => Bendéns [1] => Charlies) [date] => 2019-07-16 [placeadress] => Folkparksgatan 3A )
[8] =>
Array ( [id] => 224 [place_id] => Allhuset Södertälje [name] => Cedrix [date] => 2019-07-16 [placeadress] => Barrtorpsvägen 1A ) )
Here is my updated code
$sql = "SELECT `schedule`.`id`,`schedule`.`place_id`,`schedule`.`name`,`schedule`.`date`,`places`.`placeadress` FROM `schedule` INNER JOIN `places` ON `schedule`.`place_id`=`places`.`place_id` ORDER BY `date`";
$stmt = $db -> prepare($sql);
$stmt -> execute();
$ArraySchedule = $stmt->fetchAll(PDO::FETCH_ASSOC);
var_export($ArraySchedule);
$DatePlace = array();
foreach ($ArraySchedule as $key => $Schedule){
$Arrayquery = "SELECT `schedule`.`id`,`schedule`.`place_id`,`schedule`.`name`,`schedule`.`date`,`places`.`placeadress` FROM `schedule` INNER JOIN `places` ON `schedule`.`place_id`=`places`.`place_id` WHERE `schedule`.`date`= :date_ AND `schedule`.`place_id` = :place_id ORDER BY `date`";
$ArrayStmt = $db->prepare($Arrayquery);
$ArrayStmt -> execute(array(":date_" => $Schedule['date'],":place_id" => $Schedule['place_id']));
//Getting every $Schedule that has the same date and place_id
if($ArrayStmt->rowCount() > 1){
//Here i want two update the name inside
//$ArrayArraySchedule with an array of names
//that has the same place and date?
}
}
print_r($ArraySchedule);

PHP - Replace array keys with a list of keys predefined

I have a multidimensional array that I get after scrapping a web.
Array
(
[Dollar N. America] => Array
(
[Name] => Dollar N. America
[Buy] => 3.311
[Sell] => 3.314
)
[Yen Japan] => Array
(
[Name] => Yen Japan
[Buy] => 0.028
[Sell] => 0.033
)
[Euro Europe] => Array
(
[Name] => Euro Europe
[Buy] => 3.752
[Sell] => 3.948
)
)
The issue is that I need to change the names of the array keys to a shorter name:
[DollarUS] - [YenJP] - [EuroEU]
In order to make it look like this:
Array
(
[DollarUS] => Array
(
[Name] => Dollar N. America
[Buy] => 3.311
[Sell] => 3.314
)
[YenJP] => Array
(
[Name] => Yen Japan
[Buy] => 0.028
[Sell] => 0.033
)
[EuroEU] => Array
(
[Name] => Euro Europe
[Buy] => 3.752
[Sell] => 3.948
)
)
I was trying several ways but I did not find the result:
foreach ($currency as $k => $v){
$currency[$k]['DolarUS'] = $currency[$k]['Dollar N. America'];
unset($monedas[$k]['Dollar N. America']);
}
$array = [
"Dollar N. America" => [
"Name" => "Dollar N. America"
"Buy" => 3.311
"Sell" => 3.314
],
"Yen Japan" => [
"Name" => "Yen Japan"
"Buy" => 0.028
"Sell" => 0.033
],
"Euro Europe" => [
"Name" => "Euro Europe"
"Buy" => 3.752
"Sell" => 3.948
]
];
$replace_with_me = ["Dollar N. America"=>"DollarUS" , "Yen Japan"=>"YenJP" , "Euro Europe"=>"EuroEU"];
foreach($array as $key=>$value){
$array[$replace_with_me[$key]] = $array[$key];
unset($array[$key])
}
var_dump($array[$key]);
You could try array_combine():
http://php.net/manual/en/function.array-combine.php
$keys = ['DollarUS','YenJP','EuroEU'];
$values = [
'Dollar N. America' => [
'Name' => 'Dollar N. America'
'Buy' => 3.311
'Sell' => 3.314
],
'Yen Japan' => [
'Name' => 'Yen Japan'
'Buy' => 0.028
'Sell' => 0.033
],
'Euro Europe' => [
'Name' => 'Euro Europe'
'Buy' => 3.752
'Sell' => 3.948
]
];
$fixedKeys = array_combine($keys,$values);

How to remove main index from array while having any value blank multidimensional array

How to remove main array index ,
ex.
original array
[4] => Array
(
[fullname] => chaman pura
[email] => chamana#gmail.com
)
[5] => Array
(
[fullname] => sagar one
[email] =>
)
[6] => Array
(
[fullname] => hello how
[email] => how#gmail.com
)
Output should be :
[4] => Array
(
[fullname] => chaman pura
[email] => chamana#gmail.com
)
[6] => Array
(
[fullname] => hello how
[email] => how#gmail.com
)
tried :
$postArr = array_map('array_filter', $postArr);
$postArr = array_filter( $postArr );
and its giving
[5] => Array
(
[fullname] => sagar one
)
its only removing child key, not removing parent index
You only have to use array_filter:
$arr = [ '4' => [ 'fullname' => 'chaman pura', 'email' => 'chamana#gmail.com' ],
'5' => [ 'fullname' => 'sagar one', 'email' => '' ],
'6' => [ 'fullname' => 'hello how', 'email' => 'how#gmail.com' ] ];
var_dump(array_filter($arr, function ($i) { return !empty($i['email']); }));
You will need to loop the array as far as I can ponder and check the internal arrays email.
$postArr = [
["fullname" => "chaman pura", "email" => "chamana#gmail.com"],
["fullname" => "sagar one", "email" => ""],
["fullname" => "hello how", "email" => "how#gmail.com"]
];
$postArrLen = count($postArr);
for($i=0; $i < $postArrLen; $i++){
if(empty($postArr[$i]['email'])){
unset($postArr[$i]);
}
}
print_r($postArr);
Additional
I suppose this could have just been a foreach
foreach($postArr as $arr){
if(empty($arr['email'])){
unset($arr);
}
}

Categories