How to compare LARGE Multidimensional arrays in PHP - php

I searched and searched over this foro and this question is not in it, please help me with this if someone can.
I have two LARGE multidimensional arrays with the following formats
$arr1 = array( array (n1,n2,..,n=5), array (n1,n2,..,n=5), n-arrays (n1,...,n5) )
Note: the subarrays of arr1 have 5 numbers each .
$arr2 = array( array (n1,n2,..,n=4), array (n1,n2,..,n=4), n-arrays (n1,...,n4) )
Note: the subarrays of arr2 have 4 numbers each .
Now, I need to remove from arr1 the sub-arrays that include the sub-arrays in arr2. Please, see below an example:
With this two arrays:
$arr1 = array(array(1,2,6,8,10), array(2,4,6,8,10), array(20,40,60,80,100));
$arr2 = array(array(1,6,8,10), array(200,400,600,800));
The code must return:
$ret = array(array(2,4,6,8,10), array(20,40,60,80,100));
Because the numbers of (1,6,8,10) are in (1,2,6,8,10)
This is that code that I'm using now, and it works, but for a limmited number of data.... I think I need something more efficient
foreach ($arr1 as $key => $a ) {
foreach ($arr2 as $a2) {
if ( count(array_diff($a, $a2)) == 1 ) {
unset($arr1[$key]); break; }
}
}
}

You can use empty() to check if all elements were removed during array_diff()
foreach ($arr1 as $key => $v1) {
foreach ($arr2 as $v2) {
if (empty(array_diff($v2, $v1))) {
unset($arr1[$key]);
break;
}
}
}
print($arr1);
Or if your sticking with count(), you can change it to something like
if ( count(array_diff($a2, $a) < 1)) { // array_diff has the $a2 first
unset($arr1[$key]); break;
}

Related

Compare all value of two array in one foreach

I've 2 array in php
$array1=array('user_id'=>'1','user_id'=>'2','user_id'=>'3');
$array2=array('invite_user_id'=>'1','invite_user_id'=>'3');
This is a result of select query wrote in codeigniter. so that is associative array. This is 2 query result one is for user list and second is for invited user list. I want check in user list which user is invited. So that I want to compare that array
foreach ($array1 as $key => $value) {
if($array2[$key]->invite_user_id==$value->user_id) {
echo "Matched";
}
}
but it compare only 2 value of array1 with array2 3rd value is not compare. How it could compare all value of array1 and array2 in above foreach loop
I found that answer
$array1=array('user_id'=>'1','user_id'=>'2','user_id'=>'3');
$array2=array('invite_user_id'=>'1','invite_user_id'=>'3');
$invitationset = [];
foreach ($array2 as $invite) {
$invitationset[$invite->invite_user_id] = $invite->invite_user_id;
}
foreach ($array1 as $key => $value) {
if(isset($invitationset[$value->user_id])){
if($invitationset[$value->id]==$value->user_id){
echo "Matched";
}
}
}
In your assoc arrays you have dublicate keys. So if you use:
print_r( $array1 );
You'll see that your array only contains the last entry:
Array ( [user_id] => 3 )
I think that is not what you have expected. So you have to use different keys like that:
$array1 = array('user_id_1'=>'1','user_id_2'=>'2','user_id_3'=>'3');
$array2 = array('invite_user_id_1'=>'1','invite_user_id_2'=>'3');
Or you even dont use assoc arrays because it is obsolete in your example but never mind:
$user_ids = array('1','2','3');
$invited_user_ids = array('1','3');
You can compare your assoc arrays like that:
$array1 = array('user_id_1'=>'1','user_id_2'=>'2','user_id_3'=>'3');
$array2 = array('invite_user_id_1'=>'1','invite_user_id_2'=>'3');
foreach ($array1 as $user_id) {
if( in_array( $user_id, $array2 ) ) {
echo "Matched id: $user_id";
}
}

merging two arrays with specified index [duplicate]

This question already has answers here:
Transpose and flatten two-dimensional indexed array where rows may not be of equal length
(4 answers)
Closed 5 months ago.
There are two arrays , the second array will always be smaller by 1 from first array. The first array contains the numbers and second array contains the mathematical operators.
$arr1 = [210,11,12];
$arr2 = ['-','/'];
the code which i have written is working on this test case only ,but when i increase the number of elements in it. It fails.
$arr1 = [210,11,12,12];
$arr2 = ['-','/','/'];
the code i have tried so far..
$arr1 = [210,11,12];
$arr2 = ['-','/'];
$arr3 = [];
for($i=0;$i<count($arr1);$i++){
if($i == 0){
$arr3[] = $arr1[0];
}
if ($i % 2 != 0) {
$arr3[] = $arr1[$i];
}
else {
if($i < (count($arr2)-1)){
$arr3[] = $arr2[$i];
}else{
$arr3[] = $arr2[$i-1];
}
}
}
array_push($arr3,end($arr1));
print_r($arr3);
the expected result will be
$arr3 = [210,'-',11,'/','12','/','12']
You can mix the two arrays together by converting columns to rows with array_map, then merging the rows.
$arr3 = array_merge(...array_map(null, $arr1, $arr2));
array_pop($arr3);
The array_map(null, $arr1, $arr2) expression will result in
[[210, '/'], [11, '/'], [12, '/'], [12, null]]
then, array_merge(...) combines all the inner arrays together into one for the final result.
array_pop will remove the trailing null which is there because of the uneven size of the two arrays, but if you're going to end up imploding this and outputting the results as a math expression, you don't need to do it since that won't show up anyway. In fact, if that is the goal you can just add the implode directly to the expression above.
echo implode(' ', array_merge(...array_map(null, $arr1, $arr2)));
Loop the first array and use $key =>.
Then you build the new array in the loop and if $arr2 has a value with the same key, add it after the $arr1 value.
$arr1 = [210,11,12,12];
$arr2 = ['-','/','/'];
foreach($arr1 as $key => $val){
$arr3[] = $val;
if(isset($arr2[$key])) $arr3[] = $arr2[$key];
}
var_dump($arr3);
//[210, -, 11, /, 12, /, 12]
Provided, as you say, that the second array is always larger by one element, then this would be a simple way to do it:
function foo(array $p, array $q): array {
$r = [array_shift($p)];
foreach ($q as $x) {
$r[] = $x;
$r[] = array_shift($p);
}
return $r;
}
print_r(
foo([210,11,12], ['-', '/'])
);
print_r(
foo([210,11,12,12], ['-','/','/'])
);
https://3v4l.org/F0ud8
If the indices of the arrays are well formed, the above could be simplified to:
function foo(array $p, array $q): array {
$r = [$p[0]];
foreach ($q as $i => $x) {
$r[] = $x;
$r[] = $p[$i + 1];
}
return $r;
}
I wanted to offer a couple of approaches that do not modify the original array, accommodate the possibility of empty input arrays, and do not use more than one loop.
By prepopulating the result array with the first value from the numbers array, then iterating the operators array, you can avoid making iterated checks of isset().
Code: (Demo) (Demo without iterated array_push() calls)
$numbers = [210, 11, 12];
$operators = ['-', '/'];
$result = (array)($numbers[0] ?? []);
foreach ($operators as $i => $operator) {
array_push($result, $operator, $numbers[++$i]);
}
var_export($result);
or with array_reduce():
var_export(
array_reduce(
$operators,
function($result, $operator) use($numbers) {
static $i = 0;
array_push($result, $operator, $numbers[++$i]);
return $result;
},
(array)($numbers[0] ?? [])
)
);

Iterating a multi-dimensional array and mixing it

im trying to mix my multi dimension arrays, and it iterates fine, but the output isnt what im trying to accomplish, i need to mix the values.
array= [ [ p ,t ,j ] , [ 9 , 3 , 6 ] ];
foreach($array as $value) {
foreach($value as $key => $val) {
echo $val;
}
}
}
array output: p,9,t,3,j,6 //should be
Mine is: p,t,j,9,3,6
Simplest approach
foreach($array[0] as $key => $value) {
echo $value, $array[1][$key];
}
if i understand you this is your answer:
//creat an empty array to save the new result
$result= array();
//do this for incrementing
$i=0;
//your arrays here and looping it
$array=array(array( p ,t ,j ) , array( 9 , 3 , 6 ) );
foreach($array as $a){
if(is_array($a)){
foreach($a as $b){
$result[$i]= $b;
}//end foreach
}else{
$result[$i]= $a;
}//end else
$i++;
}//end foreach
//then print_r to show your array
print_r($result);
have a nice day ^_^
by 'mix' do you mean trying to combine the secondary arrays into one long array? If that is the case:
$finalArray = array();
foreach($array as $value) {
$finalArray = array_merge($finalArray, $value);
}
edit: now that I look at it, I didn't quite echo the output like you needed, but the output should be in the correct order in the $finalArray and this should work with any amount of inner arrays.

How to create an array of arrays from another array filtering it by a specific key of the subarrays?

I have following array of arrays:
$array = [
[A,a,1,i],
[B,b,2,ii],
[C,c,3,iii],
[D,d,4,iv],
[E,e,5,v]
];
From this one, I would like to create another array where the values are extract only if the value of third key of each subarray is, for example, greater than 3.
I thought in something like that:
if $array['2'] > 3){
$new_array[] = [$array['0'],$array['2'],$array['3']];
}
So in the end we would have following new array (note that first keys of the subarrays were eliminate in the new array):
$new_array = [
[D,4,iv],
[E,5,v]
];
In general, I think it should be made with foreach, but on account of my descripted problem I have no idea how I could do this. Here is what I've tried:
foreach($array as $value){
foreach($value as $k => $v){
if($k['2'] > 3){
$new_array[] = [$v['0'], $v['2'], $v['3']];
}
}
}
But probably there's a native function of PHP that can handle it, isn't there?
Many thanks for your help!!!
Suggest you to use array_map() & array_filter(). Example:
$array = [
['A','a',1,'i'],
['B','b',2,'ii'],
['C','c',3,'iii'],
['D','d',4,'iv'],
['E','e',5,'v']
];
$newArr = array_filter(array_map(function($v){
if($v[2] > 3) return [$v[0], $v[2], $v[3]];
}, $array));
print '<pre>';
print_r($newArr);
print '</pre>';
Reference:
array_map()
array_filter()
In the first foreach, $v is the array you want to test and copy.
You want to test $v[2] and check if it match your condition.
$new_array = [];
foreach($array as $v) {
if($v[2] > 3) {
$new_array[] = [$v[0], $v[2], $v[3]];
}
}

Foreaching an array and matching?

How would I iterate through an array (300+ items, imported via simplexml) and pull out every item that has a certain $x->channel->item->title and put that into a different array?
I can't make heads or tails of the haystack needle thing or how to push arrays
Say I have an array (needle) like: array("3332","3300","3493","8380") and I want to match if any of those appear through the big array (haystack). How do I do this?
You have to iterate over your big array, and check for the value of $x->channel->item->title. If it meets your criteria, push it into the new array:
$theArray; // Your 300+ array
$lookFor = array('firstthing', 'second thing', 'third thing');
$newArray = array();
foreach($theArray as $x) {
if ( in_array($x->channel->item->title, $lookFor) ) {
array_push($newArray, $x);
}
}
foreach($yourArray as $key => $value)
{
//do your things with $key and/or $value
}
Modifying from Joseph's loop, you can do:
$theArray; // Your 300+ array
$newArray = array();
$matchArray = array("3332","3300","3493","8380");
foreach($theArray as $x) {
if (in_array($x->channel->item->title, $matchArray)) {
array_push($newArray, $x);
}
}
Check out in_array() at http://php.net/manual/en/function.in-array.php

Categories