add data from 1 array to the other - php

after looking through loads of questions on here i still carnt find an answer that suits my situation.
im trying to join 2 fields from array #2 into array #1
Array #1
Array
(
[0] => Array
(
[id] => 1
[position] => top_banner_1
[name] => Top Banner 1
[order] => 1
)
[1] => Array
(
[id] => 2
[position] => left_banner_1
[name] => Left Banner 1
[order] => 2
)
)
Array #2
Array
(
[status] => 0
[countries] =>
[module_status] => 1
[top_banner_1_status] => 1
[top_banner_1_display] => 0
[left_banner_1_status] => 1
[left_banner_1_display] => 0
[left_banner_2_status] => 1
[left_banner_2_display] => 0
[left_banner_3_status] => 1
[left_banner_3_display] => 0
[left_banner_4_status] =>
[left_banner_4_display] => 0
[left_banner_5_status] =>
[left_banner_5_display] => 0
[center_banner_1_status] =>
[center_banner_1_display] => 0
[center_banner_2_status] =>
[center_banner_2_display] => 0
[right_banner_1_status] =>
[right_banner_1_display] => 0
[right_banner_2_status] =>
[right_banner_2_display] => 0
[right_banner_3_status] =>
[right_banner_3_display] => 0
[right_banner_4_status] =>
[right_banner_4_display] => 0
[right_banner_5_status] =>
[right_banner_5_display] => 0
[bottom_banner_1_status] =>
[bottom_banner_1_display] => 0
)
what i am trying to achive is:
Array
(
[0] => Array
(
[id] => 1
[position] => top_banner_1
[name] => Top Banner 1
[order] => 1
[top_banner_1_status] => 1
[top_banner_1_display] => 0
)
)
both of these arrays are comming from a database. there are 13 areas in array #1 so everything ive done so far is with foreach loops as array #2 data is fetched from a function that ideally i can't edit.
i've tried quite a few array_* functions but i'm not getting very far fast.

Assuming the following reasoning:
Array
(
[0] => Array
(
[id] => 1
[position] => top_banner_1
[name] => Top Banner 1
[order] => 1
[top_banner_1_status] => 1 // Added because of key is [position]_status.
[top_banner_1_display] => 0 // Added because of key is [position]_display.
)
)
I would do:
<?php
$array1 = // Array #1 from question.
$array2 = // Array #2 from question.
foreach ($array1 as $key => $item) {
$position = $item['position'];
$keySuffixes = array('_status', '_display');
foreach ($keySuffixes as $suff) {
if (array_key_exists($position . $suff, $array2)) {
$array1[$key][$position . $suff] = $array2[$position . $suff];
}
}
}
?>
Not elegant, I know :(

The trick is to construct a key according to ID to fetch data from $arr2.
foreach($arr1 as $key=>$val){
$id = $val['id'];
$tb_status_key = "top_banner_{$id}_status";
$tb_display_key = "top_banner_{$id}_display";
$arr1[$key][$tb_status_key] = $arr2[$tb_status_key];
$arr1[$key][$tb_display_key] = $arr2[$tb_display_key];
}

The structure of Array #2 is not quite apprpriate for this task. If you have the possibility, you should change it to smething like this:
Array
(
[top_banner_1] => Array (
[status] => 1
[display] => 0
)
[left_banner_1] => Array (
[status] => 1
[display] => 0
)
)
//and so on
But if this is not possible, this should work:
foreach($array1 as &$info) {
$status = $info['position'] . '_status';
$display = $info['position'] . '_display';
$info[$status] = $array2[$status];
$info[$display] = $array2[$display];
}
Otherwise, this seems to be a more elegant way:
foreach($array1 as &$info) {
$info['status'] = $array2[$info['position']]['status'];
$info['display'] = $array2[$info['position']]['display'];
}

Related

Dynamically combine subsets of data with their header row, then group/merge/flatten datasets by a shared column

I have an array of arrays like this which I get from a server's response:
$data = array (
'data1' => array (
0 =>
array (
0 => 'ID',
1 => 'PinCode',
2 => 'Date',
),
1 =>
array (
0 => '101',
1 => '454075',
2 => '2012-03-03',
),
2 =>
array (
0 => '103',
1 => '786075',
2 => '2012-09-05',
),
),
'data2' => array (
0 =>
array (
0 => 'Balance',
1 => 'ID',
),
1 =>
array (
0 => '4533',
1 => '101',
)
),
'data3' => array (
0 =>
array (
0 => 'Active',
1 => 'ID',
),
1 =>
array (
0 => 'Yes',
1 => '101',
),
2 =>
array (
0 => 'No',
1 => '103',
),
),
);
On the above array I perform kind of a left join operation to get the final output below :
Array
(
[0] => Array
(
[ID] => 101
[PinCode] => 454075
[Date] => 2012-03-03
[Balance] => 4533
[Active] => Yes
)
[1] => Array
(
[ID] => 103
[PinCode] => 786075
[Date] => 2012-09-05
[Balance] => 0
[Active] => No
)
)
I will explain how I get the output.
In all the arrays data1 , data2 and data3 the first row is the name of the columns and the remaining rows contain the data for those columns.
Firstly I take the array whose length is maximum in the $data array. Hence from $data I first select data1 array as its length is 3.
Using the following code:
$data1=$data['data1'];
$columns_data1 = $data1[0];
for($i=1;$i<=(count($data1)-1);$i++)
{
$output_data1[] = array_combine($columns_data1,$data1[$i]);
}
echo print_r($output_data1);
I get the output $output_data1 like this :
Array
(
[0] => Array
(
[ID] => 101
[PinCode] => 454075
[Date] => 2012-03-03
)
[1] => Array
(
[ID] => 103
[PinCode] => 786075
[Date] => 2012-09-05
)
)
After this I perform the following operation on data2 and data3 arrays to make their length equal to that of data1 length - 1 i.e excluding the first row which contains column names.
$data2=$data['data2'];
$columns_data2 = $data2[0];
for($i=1;$i<=(count($data1)-1);$i++)
{
if($i<count($data2))
$output_data2[] = array_combine($columns_data2,$data2[$i]);
else
$output_data2[]=array_combine($columns_data2,array('0'=>'0','1'=>'0')); //add the value as 0 to the rows and make the length equal to that of data1. Here I've take index 0 and 1 because first row in data contains two index i.e Balance and ID.
}
echo print_r($output_data2);
This code gives the following output for data2 :
Array
(
[0] => Array
(
[Balance] => 4533
[ID] => 101
)
[1] => Array
(
[Balance] => 0
[ID] => 0
)
)
Similary for data3 :
$data3=$data['data3'];
$columns_data3 = $data3[0];
for($i=1;$i<=(count($data1)-1);$i++)
{
if($i<count($data3))
$output_data3[] = array_combine($columns_data3,$data3[$i]);
else
$output_data3[]=array_combine($columns_data3,array('0'=>'0','1'=>'0'));
}
echo "<pre>"; print_r($output_data3);
gives the output :
Array
(
[0] => Array
(
[Active] => Yes
[ID] => 101
)
[1] => Array
(
[Active] => No
[ID] => 103
)
)
Next I'll combine $output_data1 and $output_data2 :
$left_join_on = array_column($output_data2, "ID");
$first_leftjoin_output = array();
foreach($output_data1 as $values){
$key = array_search($values['ID'], $left_join_on);
if($key ===false){
$key = array_search(0, $left_join_on);
}
unset($output_data2[$key]['ID']);
$first_leftjoin_output[] = array_merge($values,$output_data2[$key]);
}
echo "<pre>"; print_r($first_leftjoin_output);
gives the output :
Array
(
[0] => Array
(
[ID] => 101
[PinCode] => 454075
[Date] => 2012-03-03
[Balance] => 4533
)
[1] => Array
(
[ID] => 103
[PinCode] => 786075
[Date] => 2012-09-05
[Balance] => 0 //added 0 to balance as ID 103 didn't existed in output_data2. just like a left join of sql
)
)
Next I'll do a join on $first_leftjoin_output and $output_data3
$left_join_on_next = array_column($output_data3, "ID");
$second_leftjoin_output = array();
foreach($first_leftjoin_output as $values){
$key = array_search($values['ID'], $left_join_on_next);
if($key ===false){
$key = array_search(0, $left_join_on_next);
}
unset($output_data3[$key]['ID']);
$second_leftjoin_output[] = array_merge($values,$output_data3[$key]);
}
echo "<pre>"; print_r($second_leftjoin_output);
This step gives the final output $second_leftjoin_output which I already mentioned at the beginning of the question.
Array
(
[0] => Array
(
[ID] => 101
[PinCode] => 454075
[Date] => 2012-03-03
[Balance] => 4533
[Active] => Yes
)
[1] => Array
(
[ID] => 103
[PinCode] => 786075
[Date] => 2012-09-05
[Balance] => 0
[Active] => No
)
)
Hence this way I left joined all the three arrays based on matching ID field.
As you can see I'm doing all this in a hard coded way.
If my $data array contains data4 then again I'll have add the code to get $third_leftjoin_output.
I want this process to be dynamic.
I want a dynamic solution such that I just have to pass the $data array and the name of the feild the left join is going to be based on.
Something like this :
$output = left_join_function($data,"ID");
and this function should return the mentioned output. Or any other better solution would be also very helpful.
I'm not able to figure out how this can be done in a neat way.
As you mentioned, you can use a function (https://www.php.net/manual/de/functions.user-defined.php)
function foo($arg_1, $arg_2, /* ..., */ $arg_n)
{
echo "Example function.\n";
return $retval;
}
For you:
function dataJoinStep1($array)
{
// Do something with your array, left join etc.
return $array;
}
You can call the function in a loop (while/for/etc) dataJoinStep1($data)
My recommendation is robust enough to work on a dynamic number of data subsets, but it relies on the fact that all subsets are related by their ID value.
Iterate each group, separate the header data and combine it with subsequent rows within the group.
In the same loop, use first level keys to associate data from previously encountered groups (with the same first level key) and merge related data before pushing it into the result array. When finished iterating, call array_values() to re-index the result array.
Code: (Demo)
var_export(
array_values(
array_reduce(
$data,
function ($result, $group) {
$header = array_shift($group);
$idIndex = array_search('ID', $header);
foreach ($group as $row) {
$result[$row[$idIndex]] = array_merge(
$result[$row[$idIndex]] ?? [],
array_combine($header, $row)
);
}
return $result;
},
[]
)
)
);

How to remove subarrays based on duplicate element in subarray? [duplicate]

This question already has answers here:
Filter/Remove rows where column value is found more than once in a multidimensional array
(4 answers)
Closed 9 months ago.
How can I check and remove duplicates from the array based on ProductReference?
This is my array:
Array
(
[0] => Array
(
[Order] => 1
[Name] => pro book 40X80
[ProductReference] => FM7291
[Description] => pro book
[Product_type] => photobook
[Pages] => 20
[AdicRange] => 2
[Width] => 40
[Height] => 40
[AvailableOption] => 0
[PicPreviews] => Array
(
[PicPreview] => Array
(
[UrlOriginal] => http://dnmyog93u35ow.cloudfront.net/assets/software/xl_1491302876209.png
[UrlThumb] => http://dnmyog93u35ow.cloudfront.net/assets/software/xs_1491302876209.png
)
)
[SubCategories] => Array
(
)
)
[1] => Array
(
[Order] => 1
[Name] => pro book 40X80
[ProductReference] => FM7291
[Description] => pro book
[Product_type] => photobook
[Pages] => 20
[AdicRange] => 2
[Width] => 40
[Height] => 40
[AvailableOption] => 0
[PicPreviews] => Array
(
[PicPreview] => Array
(
[UrlOriginal] => http://dnmyog93u35ow.cloudfront.net/assets/software/xl_1491302876209.png
[UrlThumb] => http://dnmyog93u35ow.cloudfront.net/assets/software/xs_1491302876209.png
)
)
[SubCategories] => Array
(
)
)
[2] => Array
(
[Order] => 2
[Name] => 21X29 booklet Ver
[ProductReference] => DF0754(A4)
[Description] => 29X21 booklet Ver
[Product_type] => photobook
[Pages] => 24
[AdicRange] => 4
[Width] => 20.3
[Height] => 29.9
[AvailableOption] => 0
[PicPreviews] => Array
(
[PicPreview] => Array
(
[UrlOriginal] => http://dnmyog93u35ow.cloudfront.net/assets/software/xl_1495636546424.jpg
[UrlThumb] => http://dnmyog93u35ow.cloudfront.net/assets/software/xs_1495636546424.jpg
)
)
[SubCategories] => Array
(
)
)
)
This one-liner will overwrite earlier subarrays when a new duplicate subarray is found: (Demo)
$array=array_values(array_column($array,null,"ProductReference"));
This two-liner will retain earlier subarrays and discard later ones: (Demo)
$rekeyed=array_column(array_reverse($array),null,"ProductReference");
sort($rekeyed);
apokryfos has identified the shortest/sweetest method to retain earlier subarrays and remove later ones: (Demo)
$array=array_unique($array,SORT_REGULAR);
// if the keys are important wrap array_unique() with array_values()
Make the unique value your key:
$newArray = array();
foreach($oldArray as $product){
$newArray[$product['ProductReference']] = $product;
}
This may solve your problem or guide you.You can remove duplicate based on any key.Yes if you can make in database query go for that, that will be better. Directly copied from php manual
<?php
$details = array(
0 => array("id"=>"1", "name"=>"Mike", "num"=>"9876543210"),
1 => array("id"=>"2", "name"=>"Carissa", "num"=>"08548596258"),
2 => array("id"=>"1", "name"=>"Mathew", "num"=>"784581254"),
);
function unique_multidim_array($array, $key) {
$temp_array = array();
$i = 0;
$key_array = array();
foreach($array as $val) {
if (!in_array($val[$key], $key_array)) {
$key_array[$i] = $val[$key];
$temp_array[$i] = $val;
}
$i++;
}
return $temp_array;
}
$details = unique_multidim_array($details,'id');
var_dump($details);
output
$details = array(
0 => array("id"=>"1","name"=>"Mike","num"=>"9876543210"),
1 => array("id"=>"2","name"=>"Carissa","num"=>"08548596258"),
);

how to parse the following php array

I am trying to parse the following php array, somehow I am getting the result, but I couldn't get the expected output.
Array:
Array (
[0] => Array (
[countNos] => 2
[question_id] => 1
[question] => Is Service Best?
[rating] => 4
)
[1] => Array (
[countNos] => 1
[question_id] => 2
[question] => How much you benifitted?
[rating] => 5
)
[2] => Array (
[countNos] => 1
[question_id] => 2
[question] => How much you benifitted?
[rating] => 2
)
)
Current code:
foreach ($ratings as $rating) {
if (!in_array($rating['question_id'], $ratingArr)) {
$ratingArr[$rating['question_id']]['question_id'] = $rating['question_id'];
$ratingArr[$rating['question_id']]['question'] = $rating['question'];
}
for ($i = 5; $i >= 1; $i--) {
if (!in_array($rating['rating'], $ratingArr[$rating['question_id']]['stars'])) {
if ($i == $rating['rating']) {
$ratingArr[$rating['question_id']]['stars'][$i] = $rating['countNos'];
}
}
}
}
This is the output I am getting:
Notice: Undefined index: stars in C:\xampp\htdocs\mibs\module\Survey\src\Survey\Service\SurveyService.php on line 153
Warning: in_array() expects parameter 2 to be array, null given in C:\xampp\htdocs\mibs\module\Survey\src\Survey\Service\SurveyService.php on line 153
Array (
[1] => Array (
[question_id] => 1
[question] => Is Service Best?
[stars] => Array (
[4] => 2
)
)
[2] => Array (
[question_id] => 2
[question] => How much you benifitted?
[stars] => Array (
[5] => 1
[2] => 1
)
)
)
But I am expecting the following output:
Array(
[1] => Array(
[question_id] => 1
[question] => Is Service Best?
[stars] => Array(
[5] => 0
[4] => 2
[3] => 0
[2] => 0
[1] => 0
)
)
[2] => Array(
[question_id] => 2
[question] => How much you benifitted?
[stars] => Array(
[5] => 1
[4] => 0
[3] => 0
[2] => 1
[1] => 0
)
)
)
How can I parse this array, I am always having this type of issue, whenever I am parsing, how can I overcome this.
You're never creating a stars sub-array in $ratingArr when you initialize a new entry, that's causing the two warnings. To get all the zero entries, you should initialize this to an array of 5 zeroes. Then you don't need a loop to add the stars, you can just fill in the appropriate entry directly.
And you need to use array_key_exists, not in_array, to check whether there's already an entry for $rating['question_id'] in $ratingArr.
foreach ($ratings as $rating) {
if (!array_key_exists($rating['question_id'], $ratingArr)) {
$ratingArr[$rating['question_id']]['question_id'] = $rating['question_id'];
$ratingArr[$rating['question_id']]['question'] = $rating['question'];
$ratingArr[$rating['question_id']]['stars'] = array_fill(1, 5, 0);
}
$ratingArr[$rating['question_id']]['stars'][$rating['rating']] = $rating['countNos'];
}
Loop through your array and check if you already have a subArray with the question id in the result array. If not, initialize the subArray. And then just add the rating.
Code:
<?php
$result = [];
foreach($array as $v){
if(!isset($result[$v["question_id"]])){
$result[$v["question_id"]] = [
"question_id" => $v["question_id"],
"question" => $v["question"],
"stars" => array_fill_keys(range(5, 1), 0),
];
}
$result[$v["question_id"]]["stars"][$v["rating"]] += $v["countNos"]
}
?>

Filter a multidimensional array - filter_array (PHP)

How do you filter this multidimensional array with array_filter() based on [channel]?
Array
(
[0] => Array
(
[268a9d2d25fc2b9765c7cd7b8a768d3e] => Array
(
[dj_name] => Emilian
[show_name] => TechnoShow
[channel] => techno
[show_image] => http://www.digitalark.ro/dieselfm/wp-content/uploads/2016/01/avatar.jpg
[time] => 0
[time_end] => 1
[sun1] => 1
[sun2] => 1
[sun3] => 1
[sun4] => 1
[sun5] => 1
)
)
[1] => Array
(
[e13268de7c56db42f8aeab2ab4c607f2] => Array
(
[dj_name] => John Doe
[show_name] => John Doe`s Trance Show
[channel] => trance
[show_image] => http://www.digitalark.ro/dieselfm/wp-content/uploads/2016/01/dummy.jpg
[time] => 11
[time_end] => 11
[mon1] => 1
[mon2] => 1
[tue2] => 1
[mon3] => 1
[fri3] => 1
[mon4] => 1
[mon5] => 1
)
)
)
Results should have only the arrays that have the value "techno", for example:
Array
(
[0] => Array
(
[268a9d2d25fc2b9765c7cd7b8a768d3e] => Array
(
[dj_name] => Emilian
[show_name] => TechnoShow
[channel] => techno
[show_image] => http://www.digitalark.ro/dieselfm/wp-content/uploads/2016/01/avatar.jpg
[time] => 0
[time_end] => 1
[sun1] => 1
[sun2] => 1
[sun3] => 1
[sun4] => 1
[sun5] => 1
)
))
I have tried using:
$data = array_filter($dataraw, function($fs) use ($genre) {return $fs['channel'] == $genre});
EDIT:
$djs = get_posts($args);
foreach ($djs as $dj) {
$temp = maybe_unserialize(get_post_meta($dj->ID, 'show_data',true));
if ($temp) $show_data[] = maybe_unserialize(get_post_meta($dj->ID, 'show_data',true));
}
$datax = array_filter($show_data, function($fs) use ($genre) {
return array_values($fs)[0]['channel'] == $genre;
});
print_r($datax);
I'll assume the parse error in your code was a copy/paste mistake. The problem is that the element passed into the function is a deeper array. Try:
return current($fs)['channel'] === $genre;
Also you might want to use === so the results are as expected.

Get array values having same key from one array and store those values in another array

I am working on a php project. I am stuck at this point.
Here is the array that I have.
[text_numeric] => Array
(
[text] => Numeric field fillable by user
[parameters] => Array
(
[prefix] => 1
[price] => 1
[sku] =>
[quantity] =>
[weight] =>
[min_value] => 1
[max_value] => 1
)
[operand] => Array
(
[op_fix_discount] => 1
[op_fix_recharge] => 1
[op_per_unit] => 1
[op_percentage] =>
)
)
[checkbox] => Array
(
[text] => Checkbox attributes
[parameters] => Array
(
[prefix] => 1
[price] => 1
[sku] => 1
[quantity] => 1
[weight] => 1
[min_value] =>
[max_value] =>
)
[operand] => Array
(
[op_fix_discount] => 1
[op_fix_recharge] => 1
[op_per_unit] =>
[op_percentage] => 1
)
)
I want to get all the values from this array with key value "text" in another array.
Like this:
Array
(
[0]=>Numeric field fillable by user
[1]=>Checkbox attributes
)
It could have been great if you had show us your efforts to achieve that but since you are new here is the codez. You can simply get it using a foreach loop,
$new_array = array();
foreach($your_array as $k=>$row){
$new_array[$k] = $row['text'];
}
print_r($new_array);
You can also use array_map,
function getTextField($a) {
return $a['text'];
}
$texts = array_map('getTextField', $your_array);
print_r($texts);

Categories