It is necessary to convert several arrays of the form:

$a1 = array(279171, 438170); $a2 = array(279171, 438156, 438157); $a3 = array(279171, 438178); $a4 = array(279172, 436113, 436115); $a5 = array(279172, 436113, 438108); $input = array($a1, $a2, $a3, $a4, $a5); 

In structure:

 $result = array( '279171' => array( '438170', '438156' = array( '438157' ), '438178' ), '279172' => array( '436113' => array( 436115, 438108 ) ) ); 

How to create a function that takes $input and returns $result ?

  • Formulate your question in Russian. - Alexey Ukolov
  • one
    @lalua, Welcome to StackOverflow in English. As the name implies, this site. Please either translate the question in English . If you choose to translate it. - user207618
  • There are several arrays of different lengths filled with numbers. It is necessary to get an associative array from them so that the first elements of the source arrays make up the first level of the associative array, the second second and so on. - lalua
  • @lalua, most of us have read and understood what is written, but this does not negate the fact that you need to write in Russian on ru .so. Translate. - user207618
  • Does a new user with a reputation of 1 have the right to edit a question? - Sergiks pm

3 answers 3

Each input array is like a branch with a leaf at the end. We pass it one by one, creating, if necessary, sub-arrays for all elements except the last. Last insert as value.

Passing the next node, see if it already exists as a petal (value, not a key), and, if there is, translate it into an array:

 $a1 = array(279171, 438170); $a2 = array(279171, 438156, 438157); $a3 = array(279171, 438178); $a4 = array(279172, 436113, 436115); $a5 = array(279172, 436113, 438108); $input = array($a1, $a2, $a3, $a4, $a5); $result = array(); foreach( $input as $item) { pushBranch( $item, $result); } function pushBranch( $arr, &$result) { $len = count( $arr); for($i=0, $cursor = &$result; $i<$len; $i++) { $el = $arr[ $i]; if( $i === $len-1 // last && !array_key_exists( $el, $cursor) && false === array_search( $el, $cursor, true)) { array_push( $cursor, $el); } else { // middle if( array_key_exists( $el, $cursor)) { $cursor = &$cursor[ $el]; } else { $key = array_search( $el, $cursor, true); if( false !== $key) unset( $cursor[ $key]); $cursor[ $el] = array(); $cursor = &$cursor[ $el]; } } } } print_r( $result); 

Result:

 Array ( [279171] => Array ( [0] => 438170 [438156] => Array ( [0] => 438157 ) [438157] => 438178 ) [279172] => Array ( [436113] => Array ( [0] => 436115 [1] => 438108 ) ) ) 

Ideone

  • Thank! Exactly what is needed. - lalua

Use links.
I easily wrote to JS , but PHP little confusing, strangely there ... :)

Js

 let a1 = [279171, 438170], a2 = [279171, 438156, 438157], a3 = [279171, 438178], a4 = [279172, 436113, 436115], a5 = [279172, 436113, 438108], input = [a1, a2, a3, a4, a5]; function transf(inp) { let res = {}; // Будущее древо результата function push(item, ref) { // Создаём ссылку на древо, которую будем подменять let pointer = ref; // Проходим по внутренностям очередного массива item.forEach(i => { if (!(i in pointer)) // Если нет ключа, создаём его pointer[i] = {}; pointer = pointer[i]; // Ставим ссылку на наш итерируемый указатель }); } inp.forEach(e => { push(e, res); // Передаём очередной массив на добавление }); return res; } console.info(transf(input)); 

Php

 $a1 = array(279171, 438170); $a2 = array(279171, 438156, 438157); $a3 = array(279171, 438178); $a4 = array(279172, 436113, 436115); $a5 = array(279172, 436113, 438108); $input = array($a1, $a2, $a3, $a4, $a5); function transf($inp){ $res = []; function push($item, &$ref){ $pointer = &$ref; foreach($item as $i){ if(!isset($pointer[$i])) $pointer[$i] = []; $pointer = &$pointer[$i]; } return $ref; } foreach($inp as $e){ push($e, $res); } return $res; } var_dump(transf($input)); 

Execution of an example online interpreter .

  • 2
    As I noted from the author of 438170, this is not an array, but just a string, you have this array with the name 438170. But maybe the author is not fundamentally. - Denis Kotlyarov
  • @DenisKotlyarov, you are very insightful. You can correct, if necessary, but the main principle of filling works. It seems to be. - user207618
  • Yes, it seems to work. I tried to write it myself, but it turned my head, it is difficult to understand what the author wanted ... And in general, the author’s idea resembles a crutch, probably there is also a connection with mysql ... - Denis Kotlyarov
  • @DenisKotlyarov, without context and application scenario, it is quite difficult to guess why this can be solved more simply than transforming arrays in a non-obvious way. - user207618

Crutch:

 $result = array(); foreach ($input as $array) { $deep = count($array); if ($deep==2) $result["'".$array[0]."'"][] = (string)$array[1]; if ($deep==3) $result["'".$array[0]."'"]["'".$array[1]."'"][] = (string)$array[2]; } 
  • Very bad crutch, such as the free honey. handicapped insurance issues. If the depth is ... say 4? Recursion is needed. - user207618
  • That the recursion is necessary - naturally, in case nesting is strictly not limited. But the implementation requires a little more time than I am willing to devote to this issue. And as I see from the “multitude” of answers - here I am not alone. - iosp
  • The rest is just too lazy, probably the heat has defaced (my reason :)). - user207618 3:38 pm