How Create Multiple array from a array? - php

I have an array in the same level.
$original = Array(
0=>"03ssss",//substr("03ssss",0,2)="03" => parent index
1=>"04aaaa",
2=>"05absd",
3=>"07sdsa",
4=>"08sdsd",
5=>"03tttt", //substr("03tttt",0,2)="03" => parent index
6=>"04xxxx, //substr("03xxxx",0,2)="04" => child index
7=>"05sdds",
8=>"07sdfd",
9=>"08sdff",
10=>"04xsax", //substr("03xxxx",0,2)="04" => child index
11=>"05sdfs",
12=>"07sdfds",
13=>"08asap",
)
How Can create from $original to multiple array something like this?
$move_level = Array(
0=>array(0=>"04aaaa 05absd 07sdsa 08sdsd"),
1=>array(0=>"04xxxx 05sdds 07sdfd 08sdff",
1=>"04xsax 05sdfs 07sdfds 08asap")
);
thanks

This splits the $original array into sub arrays at each element starting with '03':
$move_level = array();
$ary = array();
foreach($original as $value) {
if (strpos($value, '03') === 0) {
$move_level[] = $ary;
$ary = array();
} else {
$ary[] = $value;
}
}
$move_level[] = $ary;

Related

access an array defined by 'pointer'

So I have multiples empty arrays that I want to fill, let's say
$a_tab = [];
$b_tab = [];
$c_tab = [];
I have an array containing some data, let's say
$data = ['a' => 'foo', 'b' => 'bar', 'c' => 'foobar'];
I wanted to be able to do something like this :
foreach($data as $key => $value) {
$tab_name = $key . '_tab'; // so we have a variable that have the same name as one of the array we declared before
$$tab_name[$value] = $value; // this should add 'foo' into $a_tab, 'bar' in $b_tab and 'foobar' in $c_tab
}
But no value is ever added to any array...
Could someone explain me what did I do wrong ?
PS : if you don't want pseudo-code, here is the code that I had when I faced the issue :
// $tab is a parameter of the current function
$done_courses = []; // the array where we are going to put every courses that already have been added in one bifurcation tab
$regex_wz = '/\_werkzoekende/';
$regex_bd = '/\_bediende/';
$regex_op = '/\_outplacement/';
$bifurcation_keys = ['wz_tab' => $regex_wz, 'bd_tab' => $regex_bd, 'op_tab' => $regex_op];
// create the 3 arrays
$wz_tab = [];
$bd_tab = [];
$op_tab = [];
foreach($tab as $key => $value) {
foreach($bifurcation_keys as $tab_name => $regex) {
if(preg_match($regex, $key)) {
$n_k = preg_replace($regex, '', $key);
$$tab_name[$n_k] = $value;
if(!isset($done_courses[$n_k])) {
$done_courses[$n_k] = $n_k;
}
}
}
}
Did you try..
foreach($data as $key => $value) {
${$key.'_tab'}[$value] = $value;
}

Creating a dynamic hierarchical array in PHP

I have this general data structure:
$levels = array('country', 'state', 'city', 'location');
I have data that looks like this:
$locations = array(
1 => array('country'=>'USA', 'state'=>'New York', 'city'=>'NYC', 'location'=>'Central Park', 'count'=>123),
2 => array('country'=>'Germany', ... )
);
I want to create hierarchical arrays such as
$hierarchy = array(
'USA' => array(
'New York' => array(
'NYC' => array(
'Central Park' => 123,
),
),
),
'Germany' => array(...),
);
Generally I would just create it like this:
$final = array();
foreach ($locations as $L) {
$final[$L['country']][$L['state']][$L['city']][$L['location']] = $L['count'];
}
However, it turns out that the initial array $levels is dynamic and can change in values and length So I cannot hard-code the levels into that last line, and I do not know how many elements there are. So the $levels array might look like this:
$levels = array('country', 'state');
Or
$levels = array('country', 'state', 'location');
The values will always exist in the data to be processed, but there might be more elements in the processed data than in the levels array. I want the final array to only contain the values that are in the $levels array, no matter what additional values are in the original data.
How can I use the array $levels as a guidance to dynamically create the $final array?
I thought I could just build the string $final[$L['country']][$L['state']][$L['city']][$L['location']] with implode() and then run eval() on it, but is there are a better way?
Here's my implementation. You can try it out here:
$locations = array(
1 => array('country'=>'USA', 'state'=>'New York', 'city'=>'NYC', 'location'=>'Central Park', 'count'=>123),
2 => array('country'=>'Germany', 'state'=>'Blah', 'city'=>'NY', 'location'=>'Testing', 'count'=>54),
);
$hierarchy = array();
$levels = array_reverse(
array('country', 'state', 'city', 'location')
);
$lastLevel = 'count';
foreach ( $locations as $L )
{
$array = $L[$lastLevel];
foreach ( $levels as $level )
{
$array = array($L[$level] => $array);
}
$hierarchy = array_merge_recursive($hierarchy, $array);
}
print_r($hierarchy);
Cool question. A simple approach:
$output = []; //will hold what you want
foreach($locations as $loc){
$str_to_eval='$output';
for($i=0;$i<count($levels);$i++) $str_to_eval .= "[\$loc[\$levels[$i]]]";
$str_to_eval .= "=\$loc['count'];";
eval($str_to_eval); //will build the array for this location
}
Live demo
If your dataset always in fixed structure, you might just loop it
$data[] = [country=>usa, state=>ny, city=>...]
to
foreach ($data as $row) {
$result[][$row[country]][$row[state]][$row[city]] = ...
}
In case your data is dynamic and the levels of nested array is also dynamic, then the following is an idea:
/* convert from [a, b, c, d, ...] to [a][b][...] = ... */
function nested_array($rows, $level = 1) {
$data = array();
$keys = array_slice(array_keys($rows[0]), 0, $level);
foreach ($rows as $r) {
$ref = &$data[$r[$keys[0]]];
foreach ($keys as $j => $k) {
if ($j) {
$ref = &$ref[$r[$k]];
}
unset($r[$k]);
}
$ref = count($r) > 1 ? $r : reset($r);
}
return $data;
}
try this:
<?php
$locations = [
['country'=>'USA', 'state'=>'New York', 'city'=>'NYC', 'location'=>'Central Park', 'street'=>'7th Ave', 'count'=>123],
['country'=>'USA', 'state'=>'Maryland', 'city'=>'Baltimore', 'location'=>'Harbor', 'count'=>24],
['country'=>'USA', 'state'=>'Michigan', 'city'=>'Lansing', 'location'=>'Midtown', 'building'=>'H2B', 'count'=>7],
['country'=>'France', 'state'=>'Sud', 'city'=>'Marseille', 'location'=>'Centre Ville', 'count'=>12],
];
$nk = array();
foreach($locations as $l) {
$jsonstr = json_encode($l);
preg_match_all('/"[a-z]+?":/',$jsonstr,$e);
$narr = array();
foreach($e[0] as $k => $v) {
if($k == 0 ) {
$narr[] = '';
} else {
$narr[] = ":{";
}
}
$narr[count($e[0]) -1] = ":" ;
$narr[] = "";
$e[0][] = ",";
$jsonstr = str_replace($e[0],$narr,$jsonstr).str_repeat("}",count($narr)-3);
$nk [] = $ko =json_decode($jsonstr,TRUE);
}
print_r($nk);
Database have three field:
here Name conatin contry state and city name
id,name,parentid
Pass the contry result to array to below function:
$data['contry']=$this->db->get('contry')->result_array();
$return['result']=$this->ordered_menu( $data['contry'],0);
echo "<pre>";
print_r ($return['result']);
echo "</pre>";
Create Function as below:
function ordered_menu($array,$parent_id = 0)
{
$temp_array = array();
foreach($array as $element)
{
if($element['parent_id']==$parent_id)
{
$element['subs'] = $this->ordered_menu($array,$element['id']);
$temp_array[] = $element;
}
}
return $temp_array;
}

Combine arrays that have same value

I have array like this
$arr=[["a","b"],["b","c"],["d","e"],["f","c"]];
if sub arrays share same value they should be be merged to one array
expected output:
$arr=[["a","b","c","f"],["d","e"]];
I`m trying to avoid doing foreach inside foreach for solving this.
It seems your inner arrays always have 2 items. so nested loops aren't necessary. Here is a solution which I originally wrote in JS but it should work just as good and most efficient in PHP:
$arr=[["a","b"],["b","c"],["d","e"],["f","c"],["h","e"]];
$output = [];
$outputKeys = [];
$counter = 0;
foreach($arr as $V) {
if(!isset($outputKeys[$V[0]]) && !isset($outputKeys[$V[1]])) {
$output[$counter] = [$V[0], $V[1]];
$outputKeys[$V[0]] = &$output[$counter];
$outputKeys[$V[1]] = &$output[$counter];
$counter++;
}
elseif(isset($outputKeys[$V[0]]) && !isset($outputKeys[$V[1]])) {
array_push($outputKeys[$V[0]], $V[1]);
$outputKeys[$V[1]] = &$outputKeys[$V[0]];
}
elseif(!isset($outputKeys[$V[0]]) && isset($outputKeys[$V[1]])) {
array_push($outputKeys[$V[1]], $V[0]);
$outputKeys[$V[0]] = &$outputKeys[$V[1]];
}
}
var_dump($output); // [["a","b","c","f"],["d","e","h"]]
DEMO (click the execute button)
Pointers are your friends. Use them :)
The following algorithm should do what you want. It simply checks through each item and checks if it already exists in the newly created array, and if it does it adds it to that item instead of a new one:
<?php
$arr=[["a","b"],["b","c"],["d","e"],["f","c"]];
$newArr = [];
foreach ($arr as $items) {
$newKey = null;
foreach ($items as $item) {
foreach ($newArr as $newItemsKey => $newItems) {
if (in_array($item, $newItems)) {
$newKey = $newItemsKey;
break 2;
}
}
}
if ($newKey !== null) {
$newArr[$newKey] = array_merge($newArr[$newKey], $items);
} else {
$newArr[] = $items;
}
}
$newArr = array_map('array_unique', $newArr);
print_r($newArr);
Output:
Array
(
[0] => Array
(
[0] => a
[1] => b
[3] => c
[4] => f
)
[1] => Array
(
[0] => d
[1] => e
)
)
DEMO
This is solution I get for now.
$arr=[["a","b","c","f"],["d","e"]];
$sortedArray = sortFunction($arr,0,array());
function sortFunction($old,$index,$new) {
if ($index == sizeof($old)) return $new;
for ($i = 0; $i<sizeof($new); $i++) {
if (count(array_intersect($new[$i],$old[$index]))) {
$new[$i] = array_unique(array_merge($old[$index],$new[$i]), SORT_REGULAR);
return sortFunction($old,$index + 1,$new);
}
}
$new[] = $old[$index];
return sortFunction($old,$index + 1,$new);
}

How to dynamically create nested array in php

I want create a nested array from a config file dynamically.
My config file structure is like this:
parameter1 value1;
parameter2 value2;
parameter3 value3;
block1{
parameter1-1 value1-1;
parameter1-2 value1-2;
block1-1{
parameter1-1-1 value1-1-1;
parameter1-1-2 value1-1-2;
block1-1-1{
parameter1-1-1-1 value1-1-1-1;
parameter1-1-1-2 value1-1-1-2;
}
block1-1-2{
parameter1-1-2-1 value1-1-2-1;
parameter1-1-2-2 value1-1-2-2;
}
}
block1-2{
parameter1-2-1 value1-2-1;
parameter1-2-2 value1-2-2;
block1-2-1{
parameter1-2-1-1 value1-2-1-1;
parameter1-2-1-2 value1-2-1-2;
}
block1-2-2{
parameter1-2-2-1 value1-2-2-1;
parameter1-2-2-2 value1-2-2-2;
}
}
}
block2{
parameter2-1 value2-1;
parameter2-2 value2-2;
block2-1{
parameter2-1-1 value2-1-1;
parameter2-1-2 value2-1-2;
block2-1-1{
parameter2-1-1-1 value2-1-1-1;
parameter2-1-1-2 value2-1-1-2;
}
block2-1-2{
parameter2-1-2-1 value2-1-2-1;
parameter2-1-2-2 value2-1-2-2;
}
}
block2-2{
parameter2-2-1 value2-2-1;
parameter2-2-2 value2-2-2;
block2-2-1{
parameter2-2-1-1 value2-2-1-1;
parameter2-2-1-2 value2-2-1-2;
}
block2-2-2{
parameter2-2-2-1 value2-2-2-1;
parameter2-2-2-2 value2-2-2-2;
}
}
}
and i want this array dynamically in php:
$blocks = array(
$parameter => $value,
$parameter => $value,
$block => array(
$parameter => $value,
$parameter => $value,
$block => array(
$parameter => $value,
$parameter => $value,
$block => array(
$parameter => $value,
$parameter => $value
...
)
)
)
);
How to create dynamically nested array in PHP
Thanks.
UPDATE:
I read file line by line to an array and i want create above structure for edit it and write it again to config file.
I means from "dynamic" is creating array inside "for" or other similar things.
Try this... (change "conf.txt" to "your conf file name")
<?php
$file = fopen("conf.txt","r");
$array = array();
$a = createArray($file, $array);
fclose($file);
print("<pre>".print_r($a,true)."</pre>");
function createArray($file, $array){
while(! feof($file)){
$line = fgets($file);
$line = trim($line);
if ($line == ""){
continue;
}
if (strpos($line,'{') !== false){
$line = trim(str_replace('{','',$line));
$array[$line] = array();
$array[$line] = createArray($file, $array[$line]);
} else if (strpos($line,'}') !== false) {
return $array;
} else {
$line = str_replace(';','',$line);
$key = strtok($line, ' ');
$value = strtok(' ');
$array[$key] = $value;
}
}
return $array;
}
?>
Creating array dynamically:
in all PHP versions:
$foo = array();
in PHP 5.4+ (aka "short syntax"):
$foo = [];
Creating nested array dynamically:
$foo = [];
$foo['bar'] = [];
$foo['bar']['zoo'] = [];
or
$foo = [];
$bar = ['zoo' => []];
$foo['bar'] = $bar;
And finally call
print_r($foo);
to see what you got created. Both cases are equal so you will see:
Array
(
[bar] => Array
(
[zoo] => Array
(
)
)
}
Please see docs on array: http://php.net/manua/en/language.types.array.php

Add data dynamically to an Array

I want to add data to an array dynamically. How can I do that? Example
$arr1 = [
'aaa',
'bbb',
'ccc',
];
// How can I now add another value?
$arr2 = [
'A' => 'aaa',
'B' => 'bbb',
'C' => 'ccc',
];
// How can I now add a D?
There are quite a few ways to work with dynamic arrays in PHP.
Initialise an array:
$array = array();
Add to an array:
$array[] = "item"; // for your $arr1
$array[$key] = "item"; // for your $arr2
array_push($array, "item", "another item");
Remove from an array:
$item = array_pop($array);
$item = array_shift($array);
unset($array[$key]);
There are plenty more ways, these are just some examples.
$array[] = 'Hi';
pushes on top of the array.
$array['Hi'] = 'FooBar';
sets a specific index.
Let's say you have defined an empty array:
$myArr = array();
If you want to simply add an element, e.g. 'New Element to Array', write
$myArr[] = 'New Element to Array';
if you are calling the data from the database, below code will work fine
$sql = "SELECT $element FROM $table";
$query = mysql_query($sql);
if(mysql_num_rows($query) > 0)//if it finds any row
{
while($result = mysql_fetch_object($query))
{
//adding data to the array
$myArr[] = $result->$element;
}
}
You should use method array_push to add value or array to array exists
$stack = array("orange", "banana");
array_push($stack, "apple", "raspberry");
print_r($stack);
/** GENERATED OUTPUT
Array
(
[0] => orange
[1] => banana
[2] => apple
[3] => raspberry
)
*/
Like this?:
$array[] = 'newItem';
In additon to directly accessing the array, there is also
array_push — Push one or more elements onto the end of array
$dynamicarray = array();
for($i=0;$i<10;$i++)
{
$dynamicarray[$i]=$i;
}
Adding array elements dynamically to an Array And adding new element
to an Array
$samplearr=array();
$count = 0;
foreach ($rslt as $row) {
$arr['feeds'][$count]['feed_id'] = $row->feed_id;
$arr['feeds'][$count]['feed_title'] = $row->feed_title;
$arr['feeds'][$count]['feed_url'] = $row->feed_url;
$arr['feeds'][$count]['cat_name'] = $this->get_catlist_details($row->feed_id);
foreach ($newelt as $cat) {
array_push($samplearr, $cat);
}
++$count;
}
$arr['categories'] = array_unique($samplearr); //,SORT_STRING
$response = array("status"=>"success","response"=>"Categories exists","result"=>$arr);
just for fun...
$array_a = array('0'=>'foo', '1'=>'bar');
$array_b = array('foo'=>'0', 'bar'=>'1');
$array_c = array_merge($array_a,$array_b);
$i = 0; $j = 0;
foreach ($array_c as $key => $value) {
if (is_numeric($key)) {$array_d[$i] = $value; $i++;}
if (is_numeric($value)) {$array_e[$j] = $key; $j++;}
}
print_r($array_d);
print_r($array_e);
Fastest way I think
$newArray = array();
for($count == 0;$row = mysql_fetch_assoc($getResults);$count++)
{
foreach($row as $key => $value)
{
$newArray[$count]{$key} = $row[$key];
}
}

Categories