Covert flat array to Nested Array in PHP - php

Given the following input:
array('one/two/3',
'one/four/0/5',
'one/four/1/6',
'one/four/2/7',
'eight/nine/ten/11')
How can I convert it into this:
array(
'one': array(
'two': 3,
'four': array(5,6,7)
)
'eight': array(
'nine': (
'ten':11
)
}
)

$input = array ('one/two/3',
'one/four/0/5',
'one/four/1/6',
'one/four/2/7',
'eight/nine/ten/11');
$result = array ();
foreach ($input as $string) {
$data = array_reverse(explode('/', $string));
$tmp_array = array ();
foreach ($data as $val) {
if (empty($tmp_array)) {
$tmp_array = $val;
} else {
$tmp = $tmp_array;
$tmp_array = array ();
$tmp_array[$val] = $tmp;
}
}
$result = array_merge_recursive($result, $tmp_array);
}
echo "<pre>";
print_r($result);
echo "</pre>";
Output:
Array
(
[one] => Array
(
[two] => 3
[four] => Array
(
[0] => 5
[1] => 6
[2] => 7
)
)
[eight] => Array
(
[nine] => Array
(
[ten] => 11
)
)
)

It would be nice if we saw what you have tried.
$my_array = array('one/two/3',
'one/four/0/5',
'one/four/1/6',
'one/four/2/7',
'eight/nine/ten/11');
$result= array();
foreach ($my_array as $val) {
$ref = & $result;
foreach (explode("/", $val) as $val) {
if (!isset($ref[$val])) {
$ref[$val] = array();
}
$ref = & $ref[$val];
}
$ref = $val;
}
var_dump($result);

Related

Convert a one dimensional array to two dimensional array

I have an array, whose structure is basically like this:
array('id,"1"', 'name,"abcd"', 'age,"30"')
I want to convert it into a two dimensional array, which has each element as key -> value:
array(array(id,1),array(name,abcd),array(age,30))
Any advice would be appreciated!
I tried this code:
foreach ($datatest as $lines => $value){
$tok = explode(',',$value);
$arrayoutput[$tok[0]][$tok[1]] = $value;
}
but it didn't work.
Assuming you want to remove all quotation marks as per your question:
$oldArray = array('id,"1"', 'name,"abcd"', 'age,"30"')
$newArray = array();
foreach ($oldArray as $value) {
$value = str_replace(array('"',"'"), '', $value);
$parts = explode(',', $value);
$newArray[] = $parts;
}
You can do something like this:
$a = array('id,"1"', 'name,"abcd"', 'age,"30"');
$b = array();
foreach($a as $first_array)
{
$temp = explode("," $first_array);
$b[$temp[0]] = $b[$temp[1]];
}
$AR = array('id,"1"', 'name,"abcd"', 'age,"30"');
$val = array();
foreach ($AR as $aa){
$val[] = array($aa);
}
print_r($val);
Output:
Array ( [0] => Array ( [0] => id,"1" ) [1] => Array ( [0] => name,"abcd" ) [2] => Array ( [0] => age,"30" ) )
With array_map function:
$arr = ['id,"1"', 'name,"abcd"', 'age,"30"'];
$result = array_map(function($v){
list($k,$v) = explode(',', $v);
return [$k => $v];
}, $arr);
print_r($result);
The output:
Array
(
[0] => Array
(
[id] => "1"
)
[1] => Array
(
[name] => "abcd"
)
[2] => Array
(
[age] => "30"
)
)

Loop through multidimensional array and echo values

I have a multidimensional array that I would like to loop through and print the values that are stored in the array. This is the end result I am looking to achieve
{ "lat": 52.4469601, "lon": -1.93685532},
{ "lat": 52.44332417, "lon": -1.9426918},
{ "lat": 52.43987106, "lon": -1.9329071}
How would I go about printing the values like this? Currently this is how I am printing the whole array:
$enc = 'NTIuNDQ2OTYwMSwtMS45MzY4NTUzMnw1Mi40NDMzMjQxNywtMS45NDI2OTE4fDUyLjQzOTg3MTA2LC0xLjkzMjkwNzF8NTIuNDQ1NDk1MywtMS45MjU4MjYwN3w';
$decoded = base64_decode($enc);
$trim = trim($decoded, '|');
$data = explode('|', $decoded);
$out = array();
$step = 0;
$last = count($data);
$last--;
foreach( $data as $key => $item ) {
foreach (explode(',', $item) as $value) {
$out[$key][] = $value;
}
}
echo "<pre>";
print_r( $out );
echo "</pre>";
And the output looks like:
Array
(
[0] => Array
(
[0] => 52.4469601
[1] => -1.93685532
)
[1] => Array
(
[0] => 52.44332417
[1] => -1.9426918
)
[2] => Array
(
[0] => 52.43987106
[1] => -1.9329071
)
[3] => Array
(
[0] => 52.4454953
[1] => -1.92582607
)
)
If your data is exported always with "lat" and "lon" pairs then you can do this:
foreach( $data as $key => $item ) {
$lat = true;
foreach (explode(',', $item) as $value) {
if($lat == true){
$out[$key]["lat"] = $value;
$lat = false;
} else {
$out[$key]["lon"] = $value;
}
}
}
An other way to do it using a stream approach:
$enc = 'NTIuNDQ2OTYwMSwtMS45MzY4NTUzMnw1Mi40NDMzMjQxNywtMS45NDI2OTE4fDUyLjQzOTg3MTA2LC0xLjkzMjkwNzF8NTIuNDQ1NDk1MywtMS45MjU4MjYwN3w';
$handle = fopen("data:text/plain;base64,$enc", 'r');
$res = [];
while ( false !== $rec = stream_get_line($handle, 0, '|') ) {
$res[] = array_combine(['lat', 'lon'], str_getcsv($rec));
}
echo json_encode($res);
$enc = 'NTIuNDQ2OTYwMSwtMS45MzY4NTUzMnw1Mi40NDMzMjQxNywtMS45NDI2OTE4fDUyLjQzOTg3MTA2LC0xLjkzMjkwNzF8NTIuNDQ1NDk1MywtMS45MjU4MjYwN3w';
$decodedArr = explode('|', base64_decode($enc));
$latLong = [];
foreach ($decodedArr as $latLongStr) {
if (!$latLongStr) {
continue;
}
$temp = explode(',', $latLongStr);
$latLong[] = ['lat' => $temp[0], 'lon' => $temp[1]];
}
echo json_encode($latLong);
Output
[{"lat":"52.4469601","lon":"-1.93685532"},{"lat":"52.44332417","lon":"-1.9426918"},{"lat":"52.43987106","lon":"-1.9329071"},{"lat":"52.4454953","lon":"-1.92582607"}]

Convert an array of array into one array

I have a problem with my array, So my array is :
Array
(
[0] => Array
(
[0] => Array
(
[sValue] => 1
)
[1] => Array
(
[sValue] => 2
)
)
)
I want to get this array :
Array
(
[0]=>1
[1]=>2
)
I tried like this, but not work, it's get only the sValue = 1:
for($i=0;$i<count($aExpectedAnswers);$i++){
foreach($aExpectedAnswers as $answer){
$aFormatedAnswers[] = '\''.$answer[$i]['sValue'].'\'';
}
}
Help me please, Thx in advance
$aFormatedAnswers = [];
foreach ($aExpectedAnswers as $answer) {
if (is_array($answer)) {
foreach ($answer as $item) {
$aFormatedAnswers[] = $item;
}
} else {
$aFormatedAnswers[] = $answer;
}
$result = array();
foreach($initial as $subArray){
foreach($subArrray as $value){
$result[] = $value;
}
}
print_r($result);
try this code:
$aExpectedAnswers = array(
array(
0 => array('sValue'=>1),
1 => array('sValue'=>2),
)
);
$result = array();
foreach($aExpectedAnswers as $aea){
foreach($aea as $ae){
$result[] = $ae['sValue'];
}
}
print_r($result);
hopefully helping.

Don't want Array ito combine values

I Have an array in PHP that looks like:
Array ( [2099:360] => 6-3.25 [2130:361] => 4-2.5 [2099:362] => 14-8.75 )
Notice there is Two Keys that are 2099 and one that is 2130. I Have a foreach to remove the everything after the colon. the $drop is my array
$a = array();
foreach ($drop as $part=>$drop_a){
$ex_part = explode(":", $part);
$a[$ex_part[0]] = $drop_a;
}
print_r($a);
but when I print $a it displays only the recent value of the 2099?
Array ( [2099] => 14-8.75 [2130] => 4-2.5 )
Any Successions? How can I get it to display all of the values?
Thank You for Your Help
One solution is to use a multi-dimensional array to store this strategy:
$a = array();
foreach ($drop as $part=>$drop_a){
$ex_part = explode(":", $part);
if (isset($a[$ex_part[0]])) {
$a[$ex_part[0]][] = $drop_a;
} else {
$a[$ex_part[0]] = array($drop_a);
}
}
Your resulting data-set will however be different:
Array ( [2099] => Array ( [0] => 6-3.25 [1] => 14-8.75) [2130] => Array ( [0] => 4-2.5 ) )
It may be beneficial to you to preserve the second portion after the colon :
$a = array();
foreach ($drop as $part=>$drop_a){
$ex_part = explode(":", $part);
if (isset($a[$ex_part[0]])) {
$a[$ex_part[0]][$ex_part[1]] = $drop_a;
} else {
$a[$ex_part[0]] = array($ex_part[1] => $drop_a);
}
}
Now your result is a little more meaningful:
Array ( [2099] => Array ( [360] => 6-3.25 [362] => 14-8.75) [2130] => Array ( [361] => 4-2.5 ) )
Finally you can use alternative key-naming strategy if one is already occupied:
$a = array();
foreach ($drop as $part=>$drop_a){
$ex_part = explode(":", $part);
if (isset($a[$ex_part[0]])) {
$a[altName($ex_part[0], $a)] = $drop_a;
} else {
$a[$ex_part[0]] = $drop_a;
}
}
function altName($key, $array) {
$key++; // Or however you want to do an alternative naming strategy
if (isset($array[$key])) {
return altName($key, $array); // This will eventually resolve - but be careful with the recursion
}
return $key;
}
Returns:
Array
(
[2099] => 6-3.25
[2130] => 4-2.5
[2100] => 14-8.75
)
You basically have a key and a sub key for each entry, so just put them in a multidimensional array:
$a = array();
foreach ($drop as $key => $val) {
list($key, $subKey) = explode(':', $key);
$a[$key][$subKey] = $val;
}
Gives you:
Array
(
[2099] => Array
(
[360] => 6-3.25
[362] => 14-8.75
)
[2130] => Array
(
[361] => 4-2.5
)
)
You can traverse multidimensional arrays by nesting loops:
foreach ($a as $key => $subKeys) {
foreach ($subKeys as $subKey => $val) {
echo "$key contains $subKey (value of $val) <br>";
}
}

Group pairs in array

I'm trying to group airlines with relations into single chains.
Array
(
[0] => Array
(
[0] => Aeroflot
[1] => S7
[2] => Transaero
)
[1] => Array
(
[0] => Alitalia
[1] => Lufthansa
)
[2] => Array
(
[0] => Transaero
[1] => United
)
[3] => Array
(
[0] => United
[1] => Alitalia
)
[4] => Array
(
[0] => Volotea
[1] => Iberia
)
[5] => Array
(
[0] => Transaero
[1] => Aeroflot
)
)
From that array I need to find connections between elements and combine it to groups. Expected results:
Array
(
[0] => Array
(
[0] => Aeroflot
[1] => S7
[2] => Transaero
[3] => United
[4] => Alitalia
[5] => Lufthansa
)
[1] => Array
(
[0] => Volotea
[1] => Iberia
)
)
Can anyone help with that? I've tried a dozen of ways but still get no success.
The most closest way I've tried which works but not in all cases:
function array_searchRecursive($needle,$haystack) {
foreach($haystack as $key=>$value) {
$current_key=$key;
if($needle===$value OR (is_array($value) && array_searchRecursive($needle,$value) !== false)) {
return $current_key;
}
}
return false;
}
foreach ($newarr as $key => $airlines)
{
foreach ($airlines as $lastkey => $airline)
{
$index = array_searchRecursive($airline,$newarr);
echo $airline.$index."\n";
if ($index !== false)
{
$newarr[$index] = array_merge($newarr[$index],$airlines);
$lastarr[] = $index;
}
}
}
But it doesn't match all values in array.
Recursive function will help you. You are welcome )
$arr = array(
array('Aeroflot','S7','Transaero'),
array('Alitalia','Lufthansa'),
array('Transaero','United'),
array('United','Alitalia'),
array('Volotea','Iberia'),
array('Transaero','Aeroflot')
);
function getConnections($arr,$curr_line_n=0,$num=0) {
for($i=0;$i<count($arr[$curr_line_n]);$i++) {
$cur_air_name = $arr[$curr_line_n][$i];
for($k=$curr_line_n+1; $k<count($arr); $k++) {
for($l=0;$l<count($arr[$k]);$l++) {
if ($arr[$k][$l]==$cur_air_name) {
$arr[$curr_line_n] = array_values(array_unique(array_merge($arr[$curr_line_n],$arr[$k])));
array_splice($arr,$k,1);
$num++;
$arr = getConnections($arr,$curr_line_n,$num);
}
}
}
}
$num++;
$curr_line_n++;
if ($curr_line_n!=count($arr)) {
$arr = getConnections($arr,$curr_line_n,$num);
}
return $arr;
}
print_r(getConnections($arr));
As per your example you are just grouping sub arrays by taking first sub array as reference. for example if you have any elements common in first sub array and in subsequent sub arrays then you combine them into one sub array.
<?php
$arr = array(
array('a', 'b', 'c', 'd'),
array('d', 't'),
array('t', 'f'),
array('k', 'o'),
array('p', 'z')
);
$arr_implode = array();
foreach ($arr as $key => $value) {
if (is_array($value)) {
$arr_implode[$key] = implode('', $value);
} else {
$arr_implode[$key] = $value;
}
}
$arr_key = array();
$result = array();
$count = count($arr_implode);
$tempj = 0;
for ($i = 0; $i <= $count; $i++) {
$flag = FALSE;
for ($j = ($i + 1); $j < $count; $j++) {
similar_text($arr_implode[$i], $arr_implode[$j], $percent);
if ($percent > 0) {
$result[] = array_merge($arr[$i],$arr[$j]);
break;
} else {
$result[] = $arr[$j];
break;
}
}
}
foreach($result as $key => $val){
$result[$key] = array_unique($val);
}
echo "<pre>";
print_r($result);
echo "</pre>";
?>
Try this code.
$arr = [
['Aeroflot', 'S7', 'Transaero'],
['Alitalia', 'Lufthansa'],
['Transaero', 'United'],
['United', 'Alitalia'],
['Volotea', 'Iberia'],
['Transaero', 'Aeroflot']
];
$hash = [];
$result = [];
foreach($arr as $set){
foreach($set as $el){
if(!$hash[$el]) $hash[$el] = [] ;
$hash[$el] = array_merge($hash[$el], $set);
}
}
function merge_connections(&$h, $key){
if(!$h[$key]) return [];
$data = [$key];
$rels = $h[$key];
unset($h[$key]);
foreach($rels as $rel){
if($rel==$key) continue;
$data = array_merge($data, merge_connections($h, $rel));
}
return $data;
}
foreach(array_keys($hash) as $company){
if(!$hash[$company]) continue;
array_push($result, merge_connections($hash, $company));
}
print_r($result);

Categories