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