PHP arrays combine values of the right key - php

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 )

Related

Group values in multi-dimensional array based on a key

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

find duplicates value with their keys

My array is like this,
$options = Array
(
[0] => Array
(
[value] => 180
[label] => Nokia
)
[1] => Array
(
[value] => 2341
[label] => Suisses
)
[2] => Array
(
[value] => 143
[label] => Nokia
)
[3] => Array
(
[value] => 2389
[label] => 3D Pop Art
)
)
and i want output as,
Array(
[0] => Array
(
[value] => 180
[label] => Nokia
)
[2] => Array
(
[value] => 143
[label] => Nokia
)
)
Can anyone suggest me in this.
You can try something like this:
$options = [
0 => [
'value' => 180,
'label' => 'Nokia'
],
1 => [
'value' => 2341,
'label' => 'Suisses'
],
2 => [
'value' => 143,
'label' => 'Nokia'
],
3 => [
'value' => 2389,
'label' => '3D Pop Art'
],
];
$labels = [];
$duplicates = [];
foreach ($options as $option) {
if (!empty($duplicates[$option['label']])) {
$duplicates[$option['label']][] = $option;
}
if (empty($labels[$option['label']])) {
$labels[$option['label']] = $option;
} else {
$duplicates[$option['label']] = [
$labels[$option['label']],
$option
];
}
}
It seems you are looking for group by 'label'
foreach($options as $v){
$c[$v['label']][] = $v['value'];
}
print_r($c);
Working example : https://3v4l.org/62dv0
The array_filter() function is what you are looking for:
<?php
$data = [
[
'value' => 180,
'label' => "Nokia"
],
[
'value' => 2341,
'label' => "Suisses"
],
[
'value' => 143,
'label' => "Nokia"
],
[
'value' => 2389,
'label' => "3D Pop Art"
]
];
$output = [];
array_walk($input, function($entry) use (&$output) {
$output[$entry['label']][] = $entry;
});
print_r(
array_filter(
$output,
function($entry) {
return count($entry) > 1;
}
)
);
The output obviously is:
Array
(
[Nokia] => Array
(
[0] => Array
(
[value] => 180
[label] => Nokia
)
[1] => Array
(
[value] => 143
[label] => Nokia
)
)
)
That output slightly differs from the one suggested by you. But it has the advantage that you can tell entries apart by the doubled label.

Transform multiple php arrays into one array

I need to create a set of arrays that look like this:
Array ([ID] => 55 [status] => u [resvdate] => 07/16/2018 [price] => 119.00 [source] => C)
Array ([ID] => 56 [status] => u [resvdate] => 07/17/2018 [price] => 119.00 [source] => C)
Array ([ID] => 57 [status] => u [resvdate] => 07/18/2018 [price] => 119.00 [source] => C)
from five arrays that look like this:
Array ( [resvdate1] => 07/16/2018 [resvdate2] => 07/17/2018 [resvdate3] => 07/18/2018 )
Array ( [resvdateid1] => 55 [resvdateid2] => 56 [resvdateid3] => 57 )
Array ( [resvprice1] => 119.00 [resvprice2] => 119.00 [resvprice3] => 119.00 )
Array ( [pricesource1] => C [pricesource2] => C [pricesource3] => C )
Array ( [rowstatus1] => u [rowstatus2] => u [rowstatus3] => u )
Do I just need to loop through each array and pick off the values or is there a more elegant way to do this?
Here's a go at it:
$data = [
[
"resvdate1" => "07/16/2018",
"resvdate2" => "07/17/2018",
"resvdate3" => "07/18/2018"
],
[
"resvdateid1" => 55,
"resvdateid2" => 56,
"resvdateid3" => 57
],
[
"resvprice1" => "119.00",
"resvprice2" => "119.00",
"resvprice3" => "119.00"
],
[
"pricesource1" => "C",
"pricesource2" => "C",
"pricesource3" => "C"
],
[
"rowstatus1" => "u",
"rowstatus2" => "u",
"rowstatus3" => "u"
]
];
$keys = [
"resvdate" => "resvdate",
"resvdateid" => "id",
"resvprice" => "price",
"pricesource" => "source",
"rowstatus" => "status"
];
$result = [];
foreach ($data as $a) {
$i = 0;
foreach ($a as $k => $v) {
$result[$i++][$keys[preg_replace("/\d/", "", $k)]] = $v;
}
}
print_r($result);
Output
Array
(
[0] => Array
(
[resvdate] => 07/16/2018
[id] => 55
[price] => 119.00
[source] => C
[status] => u
)
[1] => Array
(
[resvdate] => 07/17/2018
[id] => 56
[price] => 119.00
[source] => C
[status] => u
)
[2] => Array
(
[resvdate] => 07/18/2018
[id] => 57
[price] => 119.00
[source] => C
[status] => u
)
)
Explanation
This is basically a column to row mapping involving a little key adjustment along the way.

PHP - Merge 2 multidimensional array based on value

Currently, I have 2 multidimensional array and I'm looking to combine them into one giant array where the value's name in array 1 matches the value's name in array 2.
The array's look as followed...
Array1
(
[0] => Array
(
[id] => 1
[name] => test1
[desc] => test_desc
[quantity] => 3
)
[1] => Array
(
[id] => 2
[name] => test2
[desc] => test_desc
[quantity] => 33
)
)
Array2
(
[0] => Array
(
[holder] => 'John'
[name] => test1
[desc] => test_desc
[location] => ATL
)
[1] => Array
(
[holder] => 'Jackie'
[name] => test3
[desc] => test_desc
[location] => SF
)
)
I'm looking to merge the arrays where the 'name' column in array1 matches in array2 and also combine the columns in array's 1 & 2 into the final array. This should look like...
FinalArray
(
[0] => Array
(
[id] => 1
[holder] => 'John'
[name] => test1
[desc] => test_desc
[location] => ATL
[quantity] => 3
)
[1] => Array
(
[holder] => 'Jackie'
[name] => test3
[desc] => test_desc
[location] => SF
)
[2] => Array
(
[id] => 2
[name] => test2
[desc] => test_desc
[quantity] => 33
)
)
Where the "test1" combines the different columns across the 2 arrays into a new array inside the "FinalArray". I've tried researching some ideas with array_merge and array_merge_recursive but I'm not entirely sure if I'm going in the correct direction. Thanks in advance.
Try like this
$array1=[['id' => 1,'name' => 'test1','desc' => 'test_desc','quantity' => 3],
['id' => 2,'name' => 'test2','desc' => 'test_desc','quantity' => 33]];
$array2=[['holder' => 'John','name' => 'test1','desc' => 'test_desc','location' => 'ATL'],
['holder' => 'Jackie','name' => 'test3','desc' => 'test_desc','location' => 'SF']];
$final=[];
foreach ($array1 as $key1=>$data1){
foreach ($array2 as $key2=>$data2){
if($data1['name']==$data2['name']){
$final[]=$data1+$data2;
unset($array1[$key1]);
unset($array2[$key2]);
}
}
}
if(!empty($array1)){
foreach ($array1 as $value){
$final[]=$value;
}
}
if(!empty($array2)){
foreach ($array2 as $value){
$final[]=$value;
}
}
It will give output as
One more solution
function merge_by_name(array $arr1, array $arr2) {
$result = [];
foreach ($arr1 as $value) {
$key = array_search($value['name'], array_column($arr2, 'name'));
if($key !== false) {
$result[] = array_merge($value, $arr2[$key]);
unset($arr2[$key]);
} else {
$result[] = $value;
}
}
$result = array_merge($result, $arr2);
return $result;
}
Test
$arr1 = [
[
'id' => 1,
'name' => 'test1',
'desc' => 'test_desc',
'quantity' => 3
],
[
'id' => 2,
'name' => 'test2',
'desc' => 'test_desc',
'quantity' => 33
],
];
$arr2 = [
[
'holder' => 'John',
'name' => 'test1',
'desc' => 'test_desc',
'location' => 'ATL'
],
[
'holder' => 'Jackie',
'name' => 'test3',
'desc' => 'test_desc',
'location' => 'SF'
],
];
var_export(merge_by_name($arr1, $arr2));
Result
array (
0 =>
array (
'id' => 1,
'name' => 'test1',
'desc' => 'test_desc',
'quantity' => 3,
'holder' => 'John',
'location' => 'ATL',
),
1 =>
array (
'id' => 2,
'name' => 'test2',
'desc' => 'test_desc',
'quantity' => 33,
),
2 =>
array (
'holder' => 'Jackie',
'name' => 'test3',
'desc' => 'test_desc',
'location' => 'SF',
),
)

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