Find all possible combinations with two differents arrays - php

$array1 = [null, 6, null];
$array2 = [1,2,3,4];
How do I find all possible unique combinations of these two lists (Should be the same lenght of array1 and keep the 6 in the same position);
Need to return
[1, 6, 2],[1, 6, 3],[1, 6, 4],[2, 6, 3],[2, 6, 4],[3, 6, 4]

You can use the below logic
$array1 = [null, 6, null];
$array2 = [1,2,3,4];
$final = [];
for($i = 0;$i < count($array2);$i++){
for($j = $i + 1;$j < count($array2);$j++){
for($k = 0;$k < count($array1);$k++){
if(!is_null($array1[$k])){
$final[] = [$array2[$i], $array1[$k], $array2[$j]];
}
}
}
}
print_r($final);

Related

eloquent how to add all values of an array

for example i have the following codes in my controller:
foreach($-request->input('text') as $var){
$sum[] = $var;
}
$last = sizeof($request->input('text'));
$i = 0;
while($i < $last)
{
//insert code here
$i++;
}
$request->input('text') has the following values:
['1,2,3,4,5']
how do you add the values in the variable $var[] in eloquent? i tried the sum but it didn't work. someone also said ill use += sign on my increment
explode to convert comma-separated numbers into an array.
intval on all array elements using array_map to cast them into integer.
array_sum to add them all.
Try this.
$array = $request->input('text'); // ['1, 2, 3, 4, 5'];
$string_numbers = explode(', ', $array[0]); // ['1', '2', '3', '4', '5']
$numbers = array_map('intval', $string_numbers); // [1, 2, 3, 4, 5]
echo array_sum($numbers); // 15
$num = ['1,2,3,4,5']; // when $n = $request->input('text');
$numbers = explode(',', $num[0]);
$sum = array_sum($numbers);
dd($sum);
I think this will be helpful to you

How to get common minimum value in two arrays

I have a function where is checks on two arrays and returns the common minimum value in both the arrays. IT returns the correct answer when both the arrays have equal number of elements. But is the other other is bigger it does not return the correct one. How to overcome this?
<?php
$A = array(0);
$B= array(1,0);
$n = sizeof($A);
$m = sizeof($B);
sort($A);
sort($B);
$i = 0;
for ($k = 0; $k < $n; $k++) {
if ($i < $m - 1 AND $B[$i] < $A[$k])
$i += 1;
if ($A[$k] == $B[$i])
echo $A[$k];
}
echo "end";
?>
Thanks
A way simpler way would be to take the minimum value of the intersection of your arrays :
$array = array (5,6,7,8,9);
$array2 = array (9,7,5,3,4,1);
$min = min(array_intersect($array, $array2));
echo $min; // 5
Leverage PHP function array_intersect() to extract common values in two arrays, then fetch the minumum value by using min()
Like so:
<?php
$arrayOne = [1, 3, 5, 6, 7];
$arrayTwo = [0, 9, 2, 3, 4, 5];
echo min(array_intersect($arrayOne, $arrayTwo)); // 3
I would use array_intersect. It will give you an array with only values that are present in both arrays you are looking through, then you can find the lowest value in the array
$A = array(0,5,4,3,2,1,4);
$B = array(0,1,3,4);
$C = array_intersect($A, $B);
$low = $C[0];
for($i = 0; $i < count($C); $i++) {
if($C[$i] < $low)
$low = $C[$i];
}
echo "Lowest shared number is $low";

Use array_count_values() and still keep key -- PHP

Let's say I have two arrays...
$radicand_array = array(3, 5, 5, 2);
$coeff_array = array(-10, 14, 3, -6);
I'd like to be able to determine which (if any) values in $radicand_array match, AND also know what the keys are. So, in this case I would want to know that there's a match on keys 1 and 2 of $radicand_array.
I need to know this because I want to then add the corresponding key values in $coeff_array. So, in this case I would then add 14 and 3 based on the matching 5's in $radicand_array.
I've tried array_count_values(), but it doesn't seem to give the key values like I want. Is there a PHP function ready made for this?
Using the link:
Fixed. Good man!
<?php
// $radicand_array = array(3, 5, 5, 2);
$radicand_array = array(3, 5, 5, 2, 3, 3);
$coeff_array = array(-10, 14, 3, -6);
$unique = array_unique($radicand_array);
$duplicates = array_diff_assoc($radicand_array, $unique);
// Duplicate keys
$aDupes = array_keys(array_intersect($radicand_array, $duplicates));
$iSum = 0;
$iCountDupes = count( $aDupes );
for( $i = 0; $i < $iCountDupes; ++$i )
{
if( !empty( $coeff_array[ $aDupes[ $i ] ] ) )
{
$iSum = $iSum + $coeff_array[ $aDupes[ $i ] ];
}
}
var_dump( $iSum );
?>
This is an edited version of Vladimir Ramik's post to handle multiple sets of matches...
$radicand_array = array(3, 5, 5, 2, 3);
$coeff_array = array(-10, 14, 3, -6, 4);
$unique = array_unique($radicand_array);
$duplicates = array_diff_assoc($radicand_array, $unique);
$new_array = array_chunk($duplicates, 1);
// Duplicate keys
$aDupes = array_keys(array_intersect($radicand_array, $new_array[0]));
$iCountDupes = count( $aDupes );
for($i = 0; $i < $iCountDupes; ++$i){
$ans_coeff_1 += $coeff_array[$aDupes[ $i ]];
}
echo $ans_coeff_1;
// Duplicate keys
$bDupes = array_keys(array_intersect($radicand_array, $new_array[1]));
$iCountDupes = count( $bDupes );
for($i = 0; $i < $iCountDupes; ++$i){
$ans_coeff_2 += $coeff_array[$bDupes[ $i ]];
}
echo '<br>' . $ans_coeff_2;

Merge two flat indexed arrays of equal size so that values are pushed into the result in an alternating fashion

Suppose I have two arrays:
$a1 = array(0, 1, 2);
$a2 = array(3, 4, 5);
I want to be able to do a merge technique that alternates the array values and not just concatenate them. I want this result:
array(0, 3, 1, 4, 2, 5);
Is there a native way to do this as performance is an issue here since I need to do this thousands of times
Please note, I know I can do it like this:
for (var $i = 0; $i < count($a1); $i++) {
newArray[] = $a1[$i];
newArray[] = $b1[$i];
}
I'm looking for a built in way if there is a faster one.
$count = count($a1);
for ($i = 0; $i < $count; $i++) {
$newArray[] = $a1[$i];
$newArray[] = $b1[$i];
}
My work here is done.
$a1 = array(0,1,2);
$a2 = array(3,4,5);
$start = microtime(TRUE);
for($t = 0; $t < 100000; $t++)
{
$newArray = array();
$count = count($a1);
for ($i = 0; $i < $count; $i++)
{
$newArray[] = $a1[$i];
$newArray[] = $a2[$i];
}
}
echo round(microtime(TRUE) - $start, 2); # 0.6
$a1 = array(0,1,2);
$a2 = array(3,4,5);
$start = microtime(TRUE);
for($t = 0; $t < 100000; $t++)
{
$newArray = array();
for ($i = 0; $i < count($a1); $i++)
{
$newArray[] = $a1[$i];
$newArray[] = $a2[$i];
}
}
echo round(microtime(TRUE) - $start, 2); # 0.85
So pre-counting array size will be ~1/4 [citation needed] (on freakin' 100.000 iterations you will gain 0.2 in total) faster. If you put count() inside loop, it will recount on every iteration. 1/4 seems to me a reasonably faster. If you are looking for compiled function, you can stop.
P.S. Benchmark is like bikini, it shows you everything, and nothing.
Since you are "zippering" two indexed arrays, you can "transpose and flatten". I expect that this will not be quite as fast as using a for() or foreach(), but on small input arrays, there will be no noticeable drag on performance. In other words, when coding style or minimal declared variables is sought, then the following technique should be considered.
Code: (Demo)
$a1 = [0, 1, 2];
$a2 = [3, 4, 5];
var_export(
array_merge(...array_map(null, $a1, $a2))
);
Output:
array (
0 => 0,
1 => 3,
2 => 1,
3 => 4,
4 => 2,
5 => 5,
)
As a funky little function-less approach, you can push the $a1 value from the foreach() value declaration and inside the loop's body, you can push the $a2 value. Feast your eyes... (Demo)
$result = [];
foreach ($a1 as $index => $result[]) {
$result[] = $a2[$index];
}
var_export($result);
// same output as earlier snippet
For anyone that is hunting for an associative-safe technique, you could make looped slice or splice calls. Be aware that splice() will mutate/consume the input arrays in the process. (Slice Demo) (Splice Demo)
$result = [];
for ($i = 0, $count = count($a1); $i < $count; ++$i) {
$result += array_slice($a1, $i, 1)
+ array_slice($a2, $i, 1);
}
or
$result = [];
while($a1 && $a2) {
$result += array_splice($a1, 0, 1)
+ array_splice($a2, 0, 1);
}
p.s. I even build this utility snippet to offer more dynamic tooling of how many elements should be inserted and how frequently from each array while merging. See Insert elements from one array (one-at-a-time) after every second element of another array (un-even zippering).

Counting Sort in PHP

In a PHP project I have some data I want to sort using a linear time, simple counting sort:
$ar = array(7, 2, 0, 3, 8, 0, 12, 7, 6, 7);
$count = array();
foreach ($ar as $v)
$count[$v]++;
$sorted = array();
foreach ($count as $v => $c)
for ($i = 0; $i < $c; $i++)
$sorted[] = $v;
The problem is that the above obviously doesn't work. The php array works more like a hashmap than an array. The code can be made to work by inserting ksort($count) before the final loop, but ksort runs in O(nlogn) which destroys the entire point.
Is there any way to do a linear time sort in php? Perhaps using some paramter to array(), or some entirely different structure?
You didn't follow the algorithm correctly. This is O(n).
$ar = array(7, 2, 0, 3, 8, 0, 12, 7, 6, 7);
$count = array();
foreach ($ar as $v) {
$count[$v] = isset($count[$v]) ? $count[$v] + 1 : 1;
}
$sorted = array();
$min = min($ar);
$max = max($ar);
for ($i=$min; $i<=$max; $i++) {
if (isset($count[$i])) {
for ($j=0; $j<$count[$i]; $j++) {
$sorted[] = $i;
}
}
}
also, see array_count_values(), or alternatively compute the min and max inside the counting loop.
Approved answer is wrong. Correct:
$ar = array(7, 2, 0, 3, 8, 0, 12, 7, 6, 7);
$count = array();
foreach ($ar as $v) {
$count[$v] = isset($count[$v]) ? $count[$v] + 1 : 1;
}
$sorted = array();
$min = min($ar);
$max = max($ar);
for ($i=$min; $i <= $max; $i++) {
if (isset($count[$i])) {
for ($j=0; $j<$count[$i]; $j++) {
$sorted[] = $i;
}
}
}
If i understand your question AND comment correctly, just using sort($count) would work no?
$ar = array(7, 2, 0, 3, 8, 0, 12, 7, 6, 7);
$sorted = $ar;
sort($sorted);
var_dump($ar);
var_dump($sorted);
Result:
array(7,2,0,3,8,0,12,7,6,7);
array(0,0,2,3,6,7,7,7,8,12);
But i'm wondering what the foreach($ar as $v)$count[$v]++; does... doesn't really make sense...
Adding some comments to the code to show you why this doesn't do what you think it should do.
$ar = array(7, 2, 0, 3, 8, 0, 12, 7, 6, 7);
$count = array();
foreach ($ar as $v) {
// add each number in $ar to $count.
// the first number in $ar is 7, so 7 will be the first number in $count.
// because 7 is in $ar 3 times, $count[7] == 3.
$count[$v]++;
}
// the output of print_r will be very revealing:
print_r($count);
/*Array
(
[7] => 3
[2] => 1
[0] => 2
[3] => 1
[8] => 1
[12] => 1
[6] => 1
)*/
$sorted = array();
foreach ($count as $v => $c) {
// the first entry: $count[7] == 3
// so add 7 to $sorted 3 times.
// the second entry: $count[2] == 1
// so add 2 to $sorted 1 time.
// etc.
for ($i = 0; $i < $c; $i++) {
$sorted[] = $v;
}
}
This simply groups numbers together based on their location in the first array.
To get the sorted $ar in a variable of it's own ($sorted), it's pretty trivial:
$sorted = $ar;
sort($sorted);
Which makes me think that your question and comment is not giving the whole picture.
Edit: Now after you have clarified that you wanted to implement a specific algorithm (and you actually got an answer already that shows some points that were wrong implementing it first), I think it's worth to focus on another aspect of your question:
You're comparing the complexity of two (theoretical) algorithms, but you're leaving aside how the algorithms are implemented.
PHP's sort() - even based on "bad" quicksort, will outrun your own PHP usercode implementation of some other algorithm by numbers.
You just have compared the wrong parameters here. The complexity of a function does not says much when you compare a build-in PHP function with some function in your user-code.
$A = [1, 2, 2, 2, 1, 3, 3, 1, 2, 4, 5, 0, 0]; // example array
$m = max($A);
$count = array_fill(0, $m + 1, '0');
foreach ($A as $value) $count[$value] += 1;
// next step is print the numbers
$a = [];
foreach ($count as $key => $value) {
for ($i = 0; $i < $value;) {
array_push($a, $key);;
$i++;
}
}
var_dump($count); // print the sorted array
var_dump($a); // print the numbers (low to high)

Categories