Recursive PHP Tree (permutations) - php

I'm looking to write a function which creates all permutation of a list of arrays (The list is dynamical). Now I found 2 articles, http://dannyherran.com/2011/06/finding-unique-array-combinations-with-php-permutations/ and Finding cartesian product with PHP associative arrays. But I don't want to store them as multiple arrays, I want to add each array to each possibility so I can use them later.
In fact I want to multiply each array with the other.
For example:
$array = array(
array(
1,
2
),
array(
'A',
'B',
'C'),
array(
'I',
'II')
);
In this form:
Array
(
[0] => Array
(
[0] => 1
[1] => Array
(
[0] => Array
(
[0] => A
[1] => Array
(
[0] => I
[1] => II
)
)
[1] => Array
(
[0] => B
[1] => Array
(
[0] => I
[1] => II
)
)
[2] => Array
(
[0] => C
[1] => Array
(
[0] => I
[1] => II
)
)
)
)
[1] => Array
(
[0] => 2
[1] => Array
(
[0] => Array
(
[0] => A
[1] => Array
(
[0] => I
[1] => II
)
)
[1] => Array
(
[0] => B
[1] => Array
(
[0] => I
[1] => II
)
)
[2] => Array
(
[0] => C
[1] => Array
(
[0] => I
[1] => II
)
)
)
)
)
I think this big example made my problem clear. For this type of array I created a function:
foreach ($array[1] as $value) {
$return1[] = array($value, $array[2]);
}
foreach ($array[0] as $value) {
$return[] = array($value, $return1);
}
print_r($return);
Now I want to create this function inside a recursive function (so it becomes dynamical) but I got stuck. I wanted to pass the amount of arrays to the function and then iterate.
function createTree($array, $loops=3){
$b = $array[$loops-2];
foreach ($b as $v) {
$return[] = array($v, createTree($return, $loops-1));
}
print_r($return);
}
Maybe there is a total other solution to multiply the arrays? But the function which isn't recursive is easy for me, but making it recursive...
Thanks for your help

function createTree($array){
switch(count($array)) {
case 0:
die('Illegal argument.');
case 1:
return $array[0];
default:
$lastArray = array_pop($array);
$subArray = createTree($array);
foreach ($lastArray as $item) {
$return[] = array($item, $subArray);
}
return $return;
}
}
var_dump(createTree(array_reverse($array)));

Related

Php how to create custom array using 2 arrays

I need some help on below array formation. I want to create a custom array using 2 arrays.
This is my first array :-
Array
(
[0] => Array
(
[0] => 26
[1] => 0.0000000000000000
)
[1] => Array
(
[0] => 25
[1] => 0.0000000000000000
)
[2] => Array
(
[0] => 24
[1] => 0.0000000000000000
)
)
This is my second array :-
Array
(
[0] => Array
(
[0] => 24
)
[1] => Array
(
[0] => 26
)
)
I want final array as below. Can someone please suggest how to form this array.
Array
(
[0] => Array
(
[0] => 26
[1] => 0.0000000000000000
)
[2] => Array
(
[0] => 24
[1] => 0.0000000000000000
)
)
I have used below but I want it without foreach.
$finalArray = array();
foreach ($secondArray as $key => $value) {
$key = array_search($value[0], array_column($firstArray, 0));
$finalArray[] = $firstArray[$key];
}
You can use array_filter():
$finalArray = array_filter($firstArray,
fn($item) => in_array($item[0], array_column($secondArray, 0))
);
It could be more efficiant to compute allowed values first:
$allowedValues = array_column($secondArray, 0);
$finalArray = array_filter($firstArray, fn($item) => in_array($item[0], $allowedValues));
Before PHP 7.4, you have to use use() to pass variable to the anonymous function:
$finalArray = array_filter($firstArray,
function($item) use($secondArray) {
return in_array($item[0], array_column($secondArray, 0));
}
);

PHP array sort by number of items

I need to sort my array-based on the number of elements in the inner array.
It's my current array.
Array
(
[0] => Array
(
)
[1] => Array
(
[0] => 2-3
)
[2] => Array
(
[0] => 5-9
)
[3] => Array
(
[0] => 5-9
[1] => 2-3
)
)
I need to sort the array by this format.
Array
(
[3] => Array
(
[0] => 5-9
[1] => 2-3
)
[2] => Array
(
[0] => 5-9
)
[1] => Array
(
[0] => 2-3
)
[0] => Array
(
)
)
This seems to do it:
<?php
$a = [
[], ['2-3'], ['5-9'], ['5-9', '2-3']
];
$f = fn ($b, $c) => count($c) <=> count($b);
usort($a, $f);
print_r($a);
https://php.net/function.usort
i hope this answer help you
$result = array();
$sorter = array();
foreach($values as $key => $vals){
$sorter[$key]= count($vals);
}
arsort($sorter);
foreach ($sorter as $ii => $va) {
$result[$ii]=$values[$ii];
}
output

PHP remove duplicate values from multidimensional array but keep last one

i have this array
$items = Array (
[0] => Array ( [0] => xx [1] => 'update')
[1] => Array ( [0] => bx [1] => 'update')
[2] => Array ( [0] => xx [1] => 'creation')
[3] => Array ( [0] => fs [1] => 'creation')
[4] => Array ( [0] => tx [1] => 'update')
[5] => Array ( [0] => bx [1] => 'creation')
)
i'm trying to remove duplicate values based on the first element (xx,bx,ax etc)
if two elements from the same table match, i'd like to keep the last one with higher index,
the result would be like the following
$items = Array (
[0] => Array ( [0] => xx [1] => 'creation')
[1] => Array ( [0] => bx [1] => 'creation')
[2] => Array ( [0] => fs [1] => 'creation')
[3] => Array ( [0] => tx [1] => 'update')
)
keeping the last one was a bit confusing to me as i'm new to PHP.
Thank you in advance
Generic deduplication:
$result = [];
foreach ($array as $item) {
$result[$item[0]] = $item;
}
Functional:
$result = array_reduce($array, function ($acc, $i) {
return [$i[0] => $i] + $acc;
}, [])
Awesome:
array_column($array, null, 0);
Well, i found the solution,
i started bu reversing the array, then executed the following code
$taken = array();
$reverse = array_reverse($items, true);
foreach($reverse as $key => $item) {
if(!in_array($item[0], $taken)) {
$taken[] = $item[0];
} else {
unset($reverse[$key]);
}
}

How to merge multidimensional arrays where only subarrays are affected? [duplicate]

This question already has answers here:
Merge row data from multiple arrays
(6 answers)
Closed 5 months ago.
here: Transforming array values in elements of a subarray using PHP I asked quite the same, but the arrays were flatter. I tried to adapt the code, but unfortunately without success.
How could I merge following arrays so the second array won't be added after the end of the first array, but each subarray of the first array will receive the correspondent values of subarrays of the second. In other words, I want to merge the subarrays. Here my example:
Array 01:
Array01 (
[0] => Array
(
[0] => 40292633
[1] => 412
)
[1] => Array
(
[0] => 41785603
[1] => 382
)
[2] => Array
(
[0] => 48792980
[1] => 373
)
[3] => Array
(
[0] => 44741143
[1] => 329
))
Array 02:
Array02(
[0] => Array
(
[0] => 3460581
[1] => 1407424B1
[2] => 951753
)
[1] => Array
(
[0] => 3484251
[1] => 1028325B1
[2] => 159357
)
[2] => Array
(
[0] => 3519102
[1] => 0586365A1
[2] => 456654
)
[3] => Array
(
[0] => 3529714
[1] => 1059876A1
[2] => 852258
))
Final array:
finalArray(
[0] => Array
(
[0] => 40292633
[1] => 412
[2] => 3460581
[3] => 1407424B1
[4] => 951753
)
[1] => Array
(
[0] => 41785603
[1] => 382
[2] => 3484251
[3] => 1028325B1
[4] => 159357
)
[2] => Array
(
[0] => 48792980
[1] => 373
[2] => 3519102
[3] => 0586365A1
[4] => 456654
)
[3] => Array
(
[0] => 44741143
[1] => 329
[2] => 3529714
[3] => 1059876A1
[4] => 852258
))
Many thanks in advance!
try this code
function merge_arrays($a1, $a2) {
return array($a1, $a2);
}
$result = array_map("merge_arrays", $a1, $a2);
foreach($result as $nr)
{
$nres[] = array_merge ($nr[0], $nr[1]);
}
Try this:
$result = array();
$keys = array_unique( array_merge(array_keys($arr1), array_keys($arr2)) );
foreach($keys as $key) {
if( !array_key_exists($key, $arr1) ) {
$result[$key] = $arr2;
} else if( !array_key_exists($key, $arr2) ) {
$result[$key] = $arr1;
} else {
$result[$key] = array_merge($arr1[$key], $arr2[$key]);
}
}
It does not assume that both arrays have the same keys.
If you'd like to use array_map, this is an equivalent solution:
$keys = array_unique( array_merge(array_keys($arr1), array_keys($arr2)) );
$result = array_map(function($key) use ($arr1,$arr2) {
if( !array_key_exists($key, $arr1) ) {
return $arr2;
} else if( !array_key_exists($key, $arr2) ) {
return $arr1;
}
return array_merge($arr1[$key], $arr2[$key]);
},
$keys);
If you're sure both arrays have the same keys, you can try this:
$result = array();
foreach($arr1 as $key => $arr1val) {
$result[$key] = array_merge($arr1val, $arr2[$key]);
}

PHP - Array result

I have a big problem with a array and I want to group by key (or I don't now :( )
I get the links from mySQL and I do the following:
$lien2 = $links2['text'];
$lien2 = stripslashes($lien2);
$lien2 = htmlspecialchars($lien2);
$lien2 = nl2br($lien2);
preg_match_all('#http://.*?\.?([a-zA-Z0-9\-]+)(\.[a-zA-Z0-9]+)/[a-zA-Z0-9\/\*\-\?\&\%\=\,\.\;\#\_]+#i', $lien2, $lien2_result, PREG_SET_ORDER);
This is the array $lien2_result:
Array
(
[0] => Array
(
[0] => links1
[1] => A
)
[1] => Array
(
[0] => links2
[1] => B
)
)
Array
(
[0] => Array
(
[0] => links3
[1] => C
)
)
Array
(
[0] => Array
(
[0] => links4
[1] => B
)
)
Array
(
[0] => Array
(
[0] => links5
[1] => D
)
)
Array
(
[0] => Array
(
[0] => links6
[1] => E
)
)
and I want to get the following result:
A
links1
B
links2
links4
C
links3
D
links5
E
links6
I would adjust the query personally but if you are stuck with this resultset you could rewrite it with
foreach($lien2_result as $lien2){
foreach($lien2 as $item){
$arr[$item[1]][] = $item[0];
}
}
where print_r($arr) would result something like:
$arr = Array('A' => Array('links1'), 'B' => Array('links2','links4')); //and so on..
And actual printing the way you asked:
foreach($arr as $name => $value){
echo($name.'<br />');
foreach($value as $item){
echo($item.'<br />');
}
}
EDIT
Here's an example
http://sandbox.onlinephpfunctions.com/code/c0da893797cb2049e8346168b280a9f5b1fa145b

Categories