Compare different arrays structures - php

I have two arrays with different structures. Array 1 and Array 2 that I will name from MyList and MyFiles. I would get to return only MyList values that do not have in MyFiles. But the two arrays have different structures and I'm having trouble trying to compare
MyList
Array
(
[info] => Array
(
[0] => Array
(
[player] => Messi
[week] => Array
(
[id] => 252
[videos] => Array
(
[0] => Array
(
[id] => 2929850
[link] => goals.mp4
)
[1] => Array
(
[id] => 2929848
[link] => best.mp4
)
[2] => Array
(
[id] => 2929847
[link] => dribbling.mp4
)
)
)
)
[1] => Array
(
[player] => CR7
[week] => Array
(
[id] => 251
[videos] => Array
(
[0] => Array
(
[id] => 2929796
[link] => goals.mp4
)
[1] => Array
(
[id] => 2929795
[link] => best.mp4
)
)
)
)
[2] => Array
(
[player] => Neymar
[week] => Array
(
[id] => 253
[videos] => Array
(
[0] => Array
(
[id] => 2929794
[link] => goals.mp4
)
[1] => Array
(
[id] => 2929793
[link] => best.mp4
)
)
)
)
)
)
MyFiles Array
Array
(
[252] => Array
(
[0] => Array
(
[id] => 2929850
[link] => goals.mp4
)
[1] => Array
(
[id] => 2929848
[link] => best.mp4
)
)
[251] => Array
(
[0] => Array
(
[id] => 2929796
[link] => goals.mp4
)
[1] => Array
(
[id] => 2929795
[link] => best.mp4
)
)
)
the comparison must be made by id of the week and id of the video
I tried this but it did not work out:
$new = array();
foreach ($list['info'] as $source) {
foreach ($source["week"]['videos'] as $keys => $videos) {
foreach ($file as $key => $upload) {
if ($source["week"]["id"] == $key ) {
for($i=0; $i<count($source["week"]["videos"]); $i++){
if($videos["id"] == $upload[$i]["id"]){
unset($videos);
}else{
$new[] = $videos;
}
}
} else {
$new[] = $videos;
}
}
}
}
The expected return would be something like this.
Array
(
[info] => Array
(
[0] => Array
(
[player] => Messi
[week] => Array
(
[id] => 252
[videos] => Array
(
[2] => Array
(
[id] => 2929847
[link] => dribbling.mp4
)
)
)
)
[2] => Array
(
[player] => Neymar
[week] => Array
(
[id] => 253
[videos] => Array
(
[0] => Array
(
[id] => 2929794
[link] => goals.mp4
)
[1] => Array
(
[id] => 2929793
[link] => best.mp4
)
)
)
)
)
)

I have hidden the array in a usable format for my sake in the future should this answer be incorrect and need changing.
$desired = array();
$desired['info'][0]['player'] = 'Messi';
$desired['info'][0]['week']['id'] = 252;
$desired['info'][0]['week']['videos'][2]['id'] = 2929847;
$desired['info'][0]['week']['videos'][2]['link'] = 'dribbling.mp4';
$desired['info'][2]['player'] = 'Neymar';
$desired['info'][2]['week']['id'] = 253;
$desired['info'][2]['week']['videos'][0]['id'] = 2929794;
$desired['info'][2]['week']['videos'][0]['link'] = 'goals.mp4';
$desired['info'][2]['week']['videos'][1]['id'] = 2929793;
$desired['info'][2]['week']['videos'][1]['link'] = 'best.mp4';
$list = array();
$list["info"][0]["player"] = "Messi";
$list["info"][0]["week"]["id"] = "252";
$list["info"][0]["week"]["videos"][0]["id"] = 2929850;
$list["info"][0]["week"]["videos"][0]["link"] = "goals.mp4";
$list["info"][0]["week"]["videos"][1]["id"] = 2929848;
$list["info"][0]["week"]["videos"][1]["link"] = "best.mp4";
$list["info"][0]["week"]["videos"][2]["id"] = 2929847;
$list["info"][0]["week"]["videos"][2]["link"] = "dribbling.mp4";
$list["info"][1]["player"] = "CR7";
$list["info"][1]["week"]["id"] = "251";
$list["info"][1]["week"]["videos"][0]["id"] = 2929796;
$list["info"][1]["week"]["videos"][0]["link"] = "goals.mp4";
$list["info"][1]["week"]["videos"][1]["id"] = 2929795;
$list["info"][1]["week"]["videos"][1]["link"] = "best.mp4";
$list["info"][2]["player"] = "Neymar";
$list["info"][2]["week"]["id"] = "253";
$list["info"][2]["week"]["videos"][0]["id"] = 2929794;
$list["info"][2]["week"]["videos"][0]["link"] = "goals.mp4";
$list["info"][2]["week"]["videos"][1]["id"] = 2929793;
$list["info"][2]["week"]["videos"][1]["link"] = "best.mp4";
$file = array();
$file[252][0]['id'] = 2929850;
$file[252][0]['link'] = 'goals.mp4';
$file[252][1]['id'] = 2929848;
$file[252][1]['link'] = 'best.mp4';
$file[251][0]['id'] = 2929796;
$file[251][0]['link'] = 'goals.mp4';
$file[251][1]['id'] = 2929795;
$file[251][1]['link'] = 'best.mp4';
Edit
function array_diff_assoc_recursive($array1, $array2) {
$difference=array();
foreach ($array1 as $key => $value) {
if (is_array($value)) {
if( !isset($array2[$key]) || !is_array($array2[$key])) {
$difference[$key] = $value;
} else {
$new_diff = array_diff_assoc_recursive($value, $array2[$key]);
if (!empty($new_diff))
$difference[$key] = $new_diff;
}
} else if (!array_key_exists($key,$array2) || $array2[$key] !== $value) {
$difference[$key] = $value;
}
}
return $difference;
}
$new = array('info' => array());
foreach ($list['info'] as $key => $item) {
$a = $item['week']['videos'];
//$b = $file[$item['week']['id']] ?? []; // This is PHP7+
$b = isset($file[$item['week']['id']]) ? $file[$item['week']['id']] : [];
$c = array_diff_assoc_recursive($a, $b);
if (!empty($c)) {
$new['info'][$key] = $item;
$new['info'][$key]['week']['videos'] = $c;
}
}
You will need a function that will check the difference between the videos arrays.
What I do is simply iterate over the list array and then check the difference between that item and the file array. The difference is then stored in $c.
If there is a difference then if statement is fired which will store that player in the $new array and then replace the videos array with the difference array.
This is similar to what you were doing when you were unsetting variables.

Related

How to store array with array_push() outside loop?

I have an array, when i tried to print_r was just like this :
Array ( [user_id] => Erick ) Array ( [user_id] => Baldi) Array([user_id]=> Bintang ) Array ( [user_id] => Bagas ) Array ( [user_id] => Baim )
My Expected output just like :
Array (
Array (
[user_id] => Erick
)
Array (
[user_id] => Baldi
)
Array (
[user_id] => Bintang
)
Array (
[user_id] => Bagas
)
Array (
[user_id] => Baim
)
)
Anyone here have an idea ? I'm stuck with this.
This my php code :
public function get_userid() {
// $action = $this->input->post('action');
$customerField = $this->input->post('customer');
$projectField = $this->input->post('project');
$user_roleField = $this->input->post('role');
for ($i=0; $i<count($customerField); $i++) {
for ($j=0; $j<count($projectField); $j++) {
for ($k=0; $k<count($user_roleField); $k++) {
array_push($test, $this->get_array_push($customerField[$i], $projectField[$j], $user_roleField[$k]));
}
}
}
}
public function get_array_push($customer, $project, $user_role) {
$query = $this->db->query("SELECT user_id
FROM `ixt_user_project_list`
LEFT JOIN ixt_user_type ON ixt_user_project_list.user_type = ixt_user_type.user_type
WHERE ixt_user_project_list.user_cust_id ='".$customer."'
AND ixt_user_project_list.user_project_id ='".$project."'
AND ixt_user_type.user_owner ='".$user_role."'")->result_array();
//Filter null array
foreach ($query as $key => $value) {
print_r($value);
}
}
And this is my initial query value :
Array ( [0] => Array ( [user_id] => Erick ) ) Array ( ) Array ( ) Array ( ) Array ( ) Array ( ) Array ( [0] => Array ( [user_id] => Baldi ) [1] => Array ( [user_id] => Bintang ) ) Array ( [0] => Array ( [user_id] => Bagas ) [1] => Array ( [user_id] => Baim ) )
As #scaisEdge wrote - its happening because you use the print_r inside the foreach loop.
If you want to filter null result you can use array-filter as:
$arr = array(array("user_id" => "aaa"), null, array(), array("user_id" => null), array("otherField" => "bbb"));
$filterdResult = array_filter($arr, function($elem) {
return ($elem && array_key_exists("user_id", $elem) && !is_null($elem["user_id"]));
});
Now you can just do print_r($filterdResult );
This will output:
Array
(
[0] => Array
(
[user_id] => aaa
)
)
Edited: After setting your new input as:
$query = array(array(array("user_id" => "aaa"), null, array(), array("user_id" => null)), array(array("user_id" => "ccc"), null, array(),array("user_id" =>"ddd")));
You can use the following:
$res = array();
//Filter null array
foreach ($query as $key => $value) {
array_push($res, array_filter($value, function($elem) {
return ($elem && array_key_exists("user_id", $elem) && !is_null($elem["user_id"])); }));
}
print_r($res);
Which output:
Array
(
[0] => Array
(
[0] => Array
(
[user_id] => aaa
)
)
[1] => Array
(
[0] => Array
(
[user_id] => ccc
)
[3] => Array
(
[user_id] => ddd
)
)
)
From here flatten is available if needed.
#David Winder I tried to combine as your suggesstion with the null array filter.
$res = array();
//Filter null array
foreach ($query as $key => $value) {
if (!is_null($value)) {
$res[] = $value;
//print_r($res);
}
}
But when i print_r($res) inside the foreach loop the result became duplicate array inside all of the array value.

String to Multidimensional Array with Unique value in PHP

I have below string and want to create multidimensional array using unique value
$string = 'test.jpg|test1.jpg|^22##29##p-test.jpg^22##29##test.video^22##30##p-test2.jpg^22##30##p-test3.jpg^22##30##test4.jpg^22##31##p-CCA_Nestea.jpg^22##31##p-test3.jpg|^24##32##p-test3.jpg^24##32##p-test3.jpg^24##33##p-test3.jpg|test1.jpg';
So I have tried below code but not working
$string = 'test.jpg|test1.jpg|^22##29##p-test.jpg^22##29##test.video^22##30##p-test2.jpg^22##30##p-test3.jpg^22##30##test4.jpg^22##31##p-test22.jpg^22##31##p-test3.jpg|^24##32##p-test3.jpg^24##32##p-test3.jpg^24##33##p-test3.jpg|test1.jpg';
$content_arr = explode("|", $string);
global $db;
$arr1 = array(); $p =0;$prev_layout ='';
foreach($content_arr as $arr){
if(strpos($arr, '^') !== false) {
$l_data = explode("^",$arr);
$larr = array();
foreach ($l_data as $l) {
if(strpos($l, '##') !== false) {
$p = explode("##",$l);
$l_name = 'test lay';
$p_name = 'test pame';
if(!in_array($prev_layout,$p_arr)){
$p_arr = array();
$p_arr['l_id'] =$p[0];
$p_arr['l_name'] =$l_name;
$p_arr['l_interval'] ='';
}
$p_arr['panel'][$p++] = array('p_id'=>$p[1],'p_name'=>$p_name,'p_interval'=>'','p_element'=>$p[2]);
if($p_arr['layout_id'] != $p[0])
//if(!in_array($prev_layout,$p_arr, true)){
array_push($arr1,$p_arr);
//}
if (substr($p[2], -6) != '.video') {
$c++;
}
$prev_layout = $p[0];
}
}
}
}
?>
OUTPUT would be
[0] => Array
(
[l_id] => 22
[l_name] => test Menu
[l_interval] =>
[panel] => Array
(
[0] => Array
(
[p_id] => 29
[p_name] => Left
[p_interval] =>
[p_element] => [0] => Array
(
[0] => test.jpg,
[1] => test1.jpg
)
)
)
)
I have tried your code and modify that is it correct According to your estimated output?
$string = 'test.jpg|test1.jpg|^22##29##p-test.jpg^22##29##test.video^22##30##p-test2.jpg^22##30##p-test3.jpg^22##30##test4.jpg^22##31##p-test22.jpg^22##31##p-test3.jpg|^24##32##p-test3.jpg^24##32##p-test3.jpg^24##33##p-test3.jpg|test1.jpg';
$arr1 =$p_arr= array(); $p =0;$prev_layout ='';
$content_arr = array_filter(explode("|", $string));
global $db;
foreach($content_arr as $arr){
if(strpos($arr, '^') !== false) {
$larr = array();
$l_data = array_filter(explode("^",$arr));
foreach ($l_data as $l) {
if(strpos($l, '##') !== false) {
$l_name = 'test lay'; $p_name = 'Left';//'test pame';
$p=array();
$p = explode("##",$l);
$p0 = $p[0];
$p1 = $p[1];
unset($p[0]);unset($p[1]);
if(!array_key_exists($p0,$p_arr)){
$p_arr[$p0] = array('l_id'=>$p0,
'l_name'=>$l_name,
'l_interval'=>'','panel'=>array());
}
if(!array_key_exists($p1,$p_arr[$p0]['panel'])){
$p_arr[$p0]['panel'][$p1] = array('p_id'=>$p1,'p_name'=>$p_name,'p_interval'=>'','p_element'=>array(array_values($p)));
}else{
$p_arr[$p0]['panel'][$p1]['p_element'][] = array_values($p);
//$p_arr[$p0]['panel'][$p1]['p_element'] = array_merge($p_arr[$p0]['panel'][$p1]['p_element'],array_values($p));//if you want to mearge array
}
}
}
}
}
print_r($p_arr);die;
And Out put of that is
Array
(
[22] => Array
(
[l_id] => 22
[l_name] => test lay
[l_interval] =>
[panel] => Array
(
[29] => Array
(
[p_id] => 29
[p_name] => Left
[p_interval] =>
[p_element] => Array
(
[0] => Array
(
[0] => p-test.jpg
)
[1] => Array
(
[0] => test.video
)
)
)
[30] => Array
(
[p_id] => 30
[p_name] => Left
[p_interval] =>
[p_element] => Array
(
[0] => Array
(
[0] => p-test2.jpg
)
[1] => Array
(
[0] => p-test3.jpg
)
[2] => Array
(
[0] => test4.jpg
)
)
)
[31] => Array
(
[p_id] => 31
[p_name] => Left
[p_interval] =>
[p_element] => Array
(
[0] => Array
(
[0] => p-test22.jpg
)
[1] => Array
(
[0] => p-test3.jpg
)
)
)
)
)
[24] => Array
(
[l_id] => 24
[l_name] => test lay
[l_interval] =>
[panel] => Array
(
[32] => Array
(
[p_id] => 32
[p_name] => Left
[p_interval] =>
[p_element] => Array
(
[0] => Array
(
[0] => p-test3.jpg
)
[1] => Array
(
[0] => p-test3.jpg
)
)
)
[33] => Array
(
[p_id] => 33
[p_name] => Left
[p_interval] =>
[p_element] => Array
(
[0] => Array
(
[0] => p-test3.jpg
)
)
)
)
)
)

Create 2 dimensional array from 1 dimensional

How from this array:
Array
(
[0] => Array
(
[BLACK] => Array
(
[0] => 3171
[1] => 3173
[2] => 3175
)
[WHITE] => Array
(
[0] => 3170
[1] => 3172
[2] => 3174
)
)
[1] => Array
(
[SMALL] => Array
(
[0] => 3170
[1] => 3171
)
[MEDIUM] => Array
(
[0] => 3172
[1] => 3173
)
[LARGE] => Array
(
[0] => 3174
[1] => 3175
)
)
)
I could create something like this:
$array['BLACK']['SMALL'] = 3171;
$array['BLACK']['MEDIUM'] = 3173;
$array['BLACK']['LARGE'] = 3175;
$array['WHITE']['SMALL'] = 3170;
$array['WHITE']['MEDIUM'] = 3172;
$array['WHITE']['LARGE'] = 3174;
so create 2 dimensional array from 1 dimensional, where option is same.
<?php
$colors = array('BLACK' => array('3171','3173','3175'),'WHITE' => array('3170','3172','3174'));
$sizes = array('SMALL' => array('3170','3171'),'MEDIUM' => array('3172','3173'), 'LARGE' => array('3174','3175'));
$merged = array();
foreach ($colors as $c_key => $color) {
foreach ($color as $c_val) {
foreach ($sizes as $s_key => $size) {
foreach ($size as $s_val) {
if ($c_val == $s_val) {
$merged[$c_key][$s_key] = $c_val;
}
}
}
}
}
// var_dump($merged);
?>

Values from multidimensional to array

array fetched somewhere else:
Array
(
[0] => Array
(
[id] => 600000
[name] => test1
)
[1] => Array
(
[id] => 600300
[name] => test2
)
[2] => Array
(
[id] => 600600
[name] => test3
)
)
php:
$leftnav = array("root_id" => 0, "sub_id" => 0, "subsub_id" => 0, "subsubsub_id" => 0);
if (isset($category_data[0]['id']))
$leftnav['root_id'] = $category_data[0]['id'];
if (isset($category_data[1]['id']))
$leftnav['sub_id'] = $category_data[1]['id'];
if (isset($category_data[2]['id']))
$leftnav['subsub_id'] = $category_data[2]['id'];
if (isset($category_data[3]['id']))
$leftnav['subsubsub_id'] = $category_data[3]['id'];
Can the php code be done in a more pretty way? I have tried with array_map but all required keys in $leftnav will not be set.
$i = 0;
foreach( $leftnav as $k => $v ) {
if ( isset($category_data[$i]['id']) ) {
$leftnav[$k] = $category_data[$i]['id'];
}
$i++;
}

Arrange PHP Multidimensional Array By Inner Index

How to arrange this array by last inner index ( 0, 1, 2 ) and get the value of the last inner index as the value of each second index:
Array
(
[text] => Array
(
[grid] => Array
(
[0] => 3
[1] => 4
[2] => 5
)
[image] => Array
(
[0] =>
[1] =>
[2] =>
)
[align] => Array
(
[0] => left
[1] => right
[2] => left
)
[title] => Array
(
[0] =>
[1] =>
[2] =>
)
[content] => Array
(
[0] =>
[1] =>
[2] =>
)
)
)
And have the results as below:
Array
(
[text] => Array
(
[0] => Array
(
[grid] => 3
[image] =>
[align] => left
[title] =>
[content] =>
)
[1] => Array
(
[grid] => 4
[image] =>
[align] => right
[title] =>
[content] =>
)
[2] => Array
(
[grid] => 5
[image] =>
[align] => left
[title] =>
[content] =>
)
)
)
This will do the work
function restructure($arr){
$newArr = array();
foreach($arr as $k => $v){
foreach($v as $k1 => $v1){
foreach($v1 as $k2 => $v2){
$newArr[$k][$k2][$k1] = $v2;
}
}
}
return $newArr;
}
As SiGanteng suggested, i dont see other ways than a for/foreach loop:
function buildArray($source, $key = false)
{
// Build the new array
$new_array = array();
// Define groups
$groups = $key === false ? array_keys($source) : array($key);
foreach($groups AS $group)
{
// Get the keys
$keys = array_keys($array[$group]);
// Count the values
$num_entries = count($array[$group][$keys[0]]);
for($i = 0; $i < $num_entries; $i++)
{
foreach($keys AS $key)
{
$new_array[$group][$i][$key] = $array[$group][$key][$i];
}
}
}
return $new_array;
}
This allow you to define the key you need to build; If not specified, the function build the array for every key.
This should work.
function formatit($arr) {
$new = array();
foreach($arr as $k=>$v) {
foreach($v as $k1=>$v1) {
$new[$k1][$k] = $v1;
}
}
return $new;
}
Tested. Call it as
$arr['text'] = formatit($arr['text']);
http://ideone.com/rPzuR

Categories