array_intersect a variable amount of arrays - php

I am creating a faceted search, and I'm am trying to use array_intersect to compare the arrays and find the inputs that match.
The problem is that I will have a variable amount of arrays at anytime depending on what filters the user has selected:
$array_1, $array_2, $array_3 etc...
How do I create an array_intersect function that is dynamic in this sense?
This is what I've tried:
$next_array = 0;
for($i = 0; $i < $array_count; $i++) {
$next_array++;
if ($i == 0) {
$full_array = ${array_.$i};
} else {
if(!empty(${cvp_array.$next_array})) {
$full_array = array_intersect($full_array, ${cvp_array_.$next_array});
}
}
}
------------- EDIT -------------
I'll try to narrow down my goal a bit more:
If the user clicks three filters, this results in three arrays being created with each having individual results:
Array_1 ( [0] => 2, [1] => 4, [2] => 6 )
Array_2 ( [0] => 1, [1] => 4, [2] => 6 )
Array_3 ( [0] => 6, [1] => 7, [2] => 8 )
I need code that will find the number that is in ALL of the arrays. And if there is no common number then it would end as false or something. In the case above, I'd need it to retrieve 6. If it was only the first two arrays, it would return 4 and 6.

Try this:
$fullArray = array($array1, $array2, $array3...);
call_user_func_array('array_intersect', $fullArray);

One can use:
$intersect = array_intersect(...$fullArray);

First of all, turn those arrays into an array of arrays. Then you can use array_reduce combined with array_intersect to reduce a variable amount of arrays down to one.

You can turn those array to a single array named $total_array by using array_combine(),
then use array_intersect($full_array, $total_array). I hope this useful

Related

How to randomly select elements from an array that each element is selected only 1 time?

The following array contains entries for a competition. Some participants are shown more than others, hence the times they participate into this.
For example "pounho" has better chances than "vinylin". This is why he has more occurences than "vinylin" in the array.
My question is how to select 3 results out of the following example array, but the results must be unique, no repetitions?
Because currently, I can show 3 results, but there is repetition, for example
deou, deou, pounho.
I don't want to remove duplicates. I want the code to take into consideration that the participant "pounho" has better chances than "vinylin".
Array
(
[0] => pounho
[1] => pounho
[2] => pounho
[3] => panony
[4] => mamich
[5] => Deou
[6] => Deou
[7] => vinylin
[8] => laids
[9] => laids
)
$inputArray = [...];
$backuppedArray = $inputArray;
$randomlySelected = [];
while(count($randomlySelected) < 3 && count($backuppedArray) > 0){
$randomItem = $backuppedArray[array_rand($backuppedArray)];
if(!in_array($randomItem, $randomlySelected)){
$randomlySelected []= $randomItem;
$backuppedArray = array_diff($backuppedArray, array($randomItem));
}
}
updated answer, the more times participant is in array the more chance he has to be in random pick, it's simplest code to achieve it I could imagine
Select a random element of the array, then remove all copies of that element. Do this 3 times to get 3 different elements.
$results = array();
for ($i = 0; $i < 3; $i++) {
$index = array_rand($array);
$selected = $array[$index];
$results[] = $selected;
$array = array_diff($array, array($selected));
}
Not sure about the efficiency, especially with huge arrays, but; retrieve the first 3 values and check if they are unique. If not unique, shuffle and try again. Values with a higher frequency will have a better chance of being in the first 3:
while(count($result = array_unique(array_slice($array, 0, 3))) < 3){ shuffle($array); }
You need array_unique
$array2 = array_unique($array);
print_r($array2);
This snippet will "rank" the items in the array:
$count = array_count_values($array); //Counts values and makes new array
arsort($count); //Sort that array high to low
$keys = array_keys($count); //Split the array so we can find the key that occurs the most
echo "The top v is $keys[0][1] with $keys[0][0] occurrences."

How to cut array into two

I am trying to separate an array into two separate arrays. For example, if I have an array like this
Array([0]=>Hello[1]=>I'm[2]=>Cam)
I want to split it into two arrays and add another string
Array1([0]=>Hello[1]=>There,)
Array2([0]=>I'm[1]=>Cam)
Then finally add the two together
Array([0]=>Hello[1]=>There,[2]=>I'm[3]=>Cam)
What would be the simplest way to do this?
I know I can use array merge to put the two together but I don't know how to separate them at a certain point.
I'm also doing this on a large file that will be constantly getting bigger, so I cant use array_chunk()
Looking at your end result goal, I think a shorter method to get your desired response is to use array_splice which lets you insert into a middle of an array....
$arrayVarOriginal = array('Hello', 'Im', 'Cam');
$arrayVarExtra = array('There');
array_splice($arrayVarOriginal, 1, 0, $arrayVarExtra);
This should send you back Array([0]=>Hello[1]=>There,[2]=>Im[3]=>Cam) like you wanted!
The above avoids having to split up the array.
HOWEVER
If you did want to do it the hard way, here is how you would...
$arrayVarOriginal = array('Hello', 'Im', 'Cam');
$array1stPart = array(arrayVarOriginal[0], 'There');
$array2ndPart = array_shift($array1stPart);
$finalArray = array_merge($array1stPart, $array2ndPart);
How? array_shift removes the first item from any array, so that how we get $array2ndPart.... and $array1stPart is even easier as we can just manually build up a brand new array and take the first item from $arrayVarOriginal which is at position 0 and add 'There' in as our own new position 1.
Hope that helps :)
array_shift, array_splice, and array_merge are what you need to look into.
Based from your question, here step-by-step to get what you want for your final output.
1) Split Array
$arr = array('Hello', 'I\'m', 'Cam');
$slice = count($arr) - 1;
$arr1 = array_slice($arr, 0, -$slice);
$arr2 = array_slice($arr,1);
so, you get two new array here $arr1 and $arr2
2) Add new string
$arr1[] = "There";
3) Finally, combine the array
$arr = array_merge($arr1, $arr2)
Here sample output when you print_r the $arr
Array
(
[0] => Hello
[1] => There
[2] => I'm
[3] => Cam
)
array_slice second parameter is position where you want split. So you can do this dynamically by count the array length.
$string = array("Hello","I'm","Cam");
$firstArray = array_slice($string ,0,1);
array_push($firstArray,"There,");
$secondArray = array_slice($string ,1,2);
echo "<pre>";
print_r($firstArray);
echo "==========="."<pre>";
print_r($secondArray);
echo "<pre>";
print_r(array_merge($firstArray,$secondArray));
//out put
Array
(
[0] => Hello
[1] => There,
)
===========
Array
(
[0] => I'm
[1] => Cam
)
Array
(
[0] => Hello
[1] => There,
[2] => I'm
[3] => Cam
)
Hope it will be worked for your requirement. If not or you need more specify regarding this you can clarify your need.

Two PHP arrays, unset positions that are only present in one array

I have two arrays (in PHP):
ArrayA
(
[0] => 9
[1] => 1
[2] => 2
[3] => 7
)
ArrayB
(
[0] => 1
[1] => 1
[3] => 8
)
I want to make two new arrays, where I have only the elements declared in both of the arrays, like the following:
ArrayA
(
[0] => 9
[1] => 1
[3] => 7
)
ArrayB
(
[0] => 1
[1] => 1
[3] => 8
)
In this example ArrayA[2] doesn't exist, so ArrayB[2] has been unset.
I wrote this for loop:
for ($i = 0, $i = 99999, $i++){
if (isset($ArrayA[$i]) AND isset($ArrayB[$i]) == FALSE)
{
unset($ArrayA[$i],$ArrayB[$i]);
}
}
But it's not great because it tries every index between 0 and a very big number (99999 in this case). How can I improve my code?
The function you're looking for is array_intersect_key:
array_intersect_key() returns an array containing all the entries of array1 which have keys that are present in all the arguments.
Since you want both arrays, you'll have to run it twice, with the parameters in opposite orders, as it only keeps keys from the first array. An example:
$arrayA_filtered = array_intersect_key($arrayA, $arrayB);
$arrayB_filtered = array_intersect_key($arrayB, $arrayA);
Also, although a for loop wasn't ideal in this case, in other cases where you find yourself needing to loop through sparse array (one where not every number is set), you can use a foreach loop:
foreach($array as $key => $value) {
//Do stuff
}
One very important thing to note about PHP arrays is that they are associative. You can't simply use a for loop, as the indices are not necessarily a range of integers. Consider what would happen if you applied this algorithm twice! You'd get out of bounds errors as $arrayA[2] and $arrayB[2] no longer exist!
I would iterate through the arrays using nested foreach statements. I.e.
$outputA = array();
$outputB = array();
foreach ($arrayA as $keyA => $itemA) {
foreach ($arrayB as $keyB => $itemB) {
if ($keyA == $keyB) {
$outputA[$keyA] = $itemA;
$outputB[$keyB] = $itemB;
}
}
This should give you two arrays, $outputA and $outputB, which look just like $arrayA and $arrayB, except they only include key=>value pairs if the key was present in both original arrays.
foreach($arrayA as $k=>$a)
if (!isset($arrayB[$k]))
unset($arrayA[$k];
Take a look to php : array_diff
http://docs.php.net/manual/fr/function.array-diff.php

PHP: how to add array index then cut into several array?

I have make many changes but still cannot figure out.
i have an array let say: [1,2,3,4,5,6,7,8,9,10]
i just want to ask how to add this array until index 2 and continued add for rest array then divide them by 2 array each.
input : [1,2,3,4,5,6,7,8,9,10 ];
process : [1+2+3, 4+5+6, 7+8+9, 10]
output i need : [6,15,24,10]
then i want to cut this array into 2
last output : [[6,5],[24,10]]
Thanks
Your code will be:
$data = range(1,10);
$result = array_chunk(array_map('array_sum', array_chunk($data, 3)), 2);
-please, read array functions manual
Something like this?
<?php
$array = range(1, 10);
$array = array_chunk($array, 3);
$array = array_map('array_sum', $array);
$array = array_chunk($array, 2);
print_r(
$array
);
/*
Array
(
[0] => Array
(
[0] => 6
[1] => 15
)
[1] => Array
(
[0] => 24
[1] => 10
)
)
*/
I think you can use a for cycle to sum what you need then store result in new array. Another solution is using array merge. When you've done the trick you can create a multidimensional array to get the result like [[6,5],[24,10]].
Hope it helps
Can't really see what you are getting at from the question, but I think PHP's array_chunk command may be your friend on this, http://www.php.net/manual/en/function.array-chunk.php
this will allow you to split the array into chunks of 3 (or any number) of elements with last element containing the remainder (in this case 1 element)

How to delete element and also shift the $key in array

I have an array looks like
Array
(
[0] => 1213059
[1] => 1213063
[2] =>
[3] =>
[4] => 1213072
)
I would like to make it as following:
Array
(
[0] => 1213059
[1] => 1213063
[2] => 1213072
)
Is there anyone can help me?
Many thanks
Use array_filter
Check demo here:
array_values(array_filter($your_array)); to keep your keys numerically .
array_filter will remove all elements that evaluate to false:
$array = array_filter($array);
I don't think answers above give correct fields order, as it was asked. If you only want to remove some fields from array and leave keys order untouched you could do it with
array_filter($arr) or with unset($arr[$i])
But if you want to get new order of keys, so there is no "holes", in above example to set key 4 to key 2 as keys 2 and 3 are unset, you have to use
ksort($arr)
Here is a complete example:
$arr=array(1,1,3,2,0);
print_r($arr);
echo '<br>';
unset($arr[2]);
ksort($arr);
print_r($arr);
$arr=array_values($arr);#EDITED
ksort($arr) knows not to sort array as it should, so just in case add $arr=array_values($arr); on the end #EDITED
PHP reference of ksort() is on link.
You may use this workaround.
Define this function somewhere:
function removeArrElement($inArr, $elementNr) {
for ($i = $elementNr; $i < count($inArr) - 1; $i++) {
$inArr[$i] = $inArr[$i + 1];
}
unset($inArr[count($inArr) - 1]);
return $inArr;
}
And then, when you want to remove the specific element from $yourArray, do this:
$yourArray = removeArrElement($yourArray, $nthElement);
I feel it's not the most efficient way to do this, but it works fine.

Categories