So I'm suppose to build a multidimensional array dynamically from a text file, and everything works perfectly except that the numeric keys are screwing me over...
The text file looks something like this:
a=1
b.c=2
b.d.0.e=3
b.d.0.f=4
b.d.1.e=5
b.d.1.f=6
As the array_merge_recursive doesn't work with numeric keys, the output is like:
array(2) {
["a"]=>
string(3) "1"
["b"]=>
array(2) {
["c"]=>
string(3) "2"
["d"]=>
array(4) {
[0]=>
array(1) {
["e"]=>
string(9) "3"
}
[1]=>
array(1) {
["f"]=>
string(4) "4"
}
[2]=> array(1) {
["e"]=>
string(8) "5"
}
[3]=>
array(1) {
["f"]=>
string(9) "6"
}}}}
Is there any easy solution to make the output like...?
array(2) {
["a"]=>
string(3) "1"
["b"]=>
array(2) {
["c"]=>
string(3) "2"
["d"]=>
array(2) {
[0]=>
array(2) {
["e"]=>
string(9) "3"
["f"]=>
string(4) "4"
}
[1]=>
array(3) {
["e"]=>
string(9) "5"
["f"]=>
string(4) "6"
}}}}
Thanks
You could break each bit into its components and build up the array one step at a time.
$path = "b.d.0.e";
$val = 3;
$output = array();
$parts = explode(".", $path);
// store a pointer to where we currently are in the array.
$curr =& $output;
// loop through up to the second last $part
for ($i = 0, $l = count($parts); $i < $l - 1; ++$i) {
$part = $parts[$i];
// convert numeric strings into integers
if (is_numeric($part)) {
$part = (int) $part;
}
// if we haven't visited here before, make an array
if (!isset($curr[$part])) {
$curr[$part] = array();
}
// jump to the next step
$curr =& $curr[$part];
}
// finally set the value
$curr[$parts[$l - 1]] = $val;
My output, using the same input as yours:
Array (
[a] => 1
[b] => Array (
[c] => 2
[d] => Array (
[0] => Array (
[e] => 3
[f] => 4
)
[1] => Array (
[g] => 5
[h] => 6
)
)
)
)
Or you could use eval():
$raw_data = file($txt_file, FILE_IGNORE_NEW_LINES);
foreach ($raw_data as $line) {
list($keys, $value) = explode('=', $line);
$keys = explode('.', $keys);
$arr_str = '$result';
foreach ($keys as $key) {
if (ctype_digit($key)) {
$arr_str .= "[" . $key . "]";
} else {
$arr_str .= "['" . $key . "']";
}
}
eval($arr_str . ' = $value;');
}
print_r($result);
I know this is an old one, but the best solution I have found is to use array_replace_recursive. It will achieve what you are looking to do:
$start = array(
"600" => array("total" => 100),
"700" => array("total" => 200)
);
$finish = array(
"600" => array("average" => 25),
"700" => array("average" => 50)
);
$out = array_replace_recursive($start,$finish);
var_dump($out):
array(2) {
[600]=>
array(2) {
["total"]=>
int(100)
["average"]=>
int(25)
}
[700]=>
array(2) {
["total"]=>
int(200)
["average"]=>
int(50)
}
}
Related
For example:
$string = "AND (pr.StatusCode <> 'U') AND ((pr.pkBrand = 9) OR (pr.pkBrand = 70)) AND ((pr.pkCategory = 55) OR (pr.pkCategory = 56)) AND (pr.StatusCode <> 'D')";
I would need to pull the values associate with pkBrand i.e. 9 & 70 to push into an array for use elsewhere and the values of pkCategory i.e. 55 & 56 into a separate array again for use elsewhere.
How can I do this please.
Maybe you can do something like this:
$string = "AND (pr.StatusCode <> 'U') AND ((pr.pkBrand = 9) OR (pr.pkBrand = 70)) AND ((pr.pkCategory = 55) OR (pr.pkCategory = 56)) AND (pr.StatusCode <> 'D')";
preg_match_all("/pr.pkBrand = (\d+)|pr.pkCategory = (\d+)/", $string, $matches, PREG_SET_ORDER);
The $matches array will look like this:
array(4) {
[0] =>
array(2) {
[0] =>
string(14) "pr.pkBrand = 9"
[1] =>
string(1) "9"
}
[1] =>
array(2) {
[0] =>
string(15) "pr.pkBrand = 70"
[1] =>
string(2) "70"
}
[2] =>
array(3) {
[0] =>
string(18) "pr.pkCategory = 55"
[1] =>
string(0) ""
[2] =>
string(2) "55"
}
[3] =>
array(3) {
[0] =>
string(18) "pr.pkCategory = 56"
[1] =>
string(0) ""
[2] =>
string(2) "56"
}
}
Then you can extract the values you want from this.
this is much less concise but it aims to work regardless of the field name:
<?php
$string = "AND (pr.StatusCode <> 'U') AND ((pr.pkBrand = 9) OR (pr.pkBrand = 70)) AND ((pr.pkCategory = 55) OR (pr.pkCategory = 56)) AND (pr.StatusCode <> 'D')";
$newString=trim(str_replace(')','',str_replace('(','',str_replace('OR','',str_replace('AND','',$string)))));
$tab=explode('pr.',$newString);
foreach($tab as $value) {
$value=trim(str_replace(' ','',str_replace('\'','',$value)));
$tab2[]=$value;
}
/*echo '<pre>';
var_dump($tab2);
echo '</pre>';*/
$operators=['!=','<>','<','>','='];
foreach ($tab2 as $index=>$value) {
foreach ($operators as $operator) {
$found=0;
$explode=explode($operator,$value);
if (count($explode)==1) {}//not the good one
else {
$found=1;
break;
}
}
if ($found==1) $newTab[$explode[0]][$index]=$explode[1];
}
echo '<pre>';
var_dump($newTab);
echo '</pre>';
?>
Will give you :
array(3) {
["StatusCode"]=>
array(2) {
[1]=>
string(1) "U"
[6]=>
string(1) "D"
}
["pkBrand"]=>
array(2) {
[2]=>
string(1) "9"
[3]=>
string(2) "70"
}
["pkCategory"]=>
array(2) {
[4]=>
string(2) "55"
[5]=>
string(2) "56"
}
}
I have an array structure like this
[0]=>array(3) {
["Number"]=> "L1"
["Location"]=> "Location-A"
["Qty"]=>"1"
}
[1]=>array(3) {
["Number"]=> "L1"
["Location"]=> "Location-B"
["Qty"]=> "5"
}
[2]=> array(3) {
["Number"]=> "L1"
["Location"]=> "Location-B"
["Qty"]=> "4"
}
[3]=>array(3) {
["Number"]=> "L2"
["Location"]=> "Location-B"
["Qty"]=> "5"
}
But i required below structure as ouput
[0]=>array(3) {
["Number"]=> "L1"
["Location"]=> "Location-A"
["Qty"]=>"1"
}
[1]=> array(3) {
["Number"]=> "L1"
["Location"]=> "Location-B"
["Qty"]=> "4"
}
[2]=>array(3) {
["Number"]=> "L2"
["Location"]=> "Location-B"
["Qty"]=> "5"
}
How can i remove duplicate value by Number and Location?
ksort only works for one value, i need to remove by two values , how can i achieve this PHP ?
$ordered = array();
foreach ($data as $da)
{
$ordered[$da['Number']] = $da;
$ordered[$da['Location']] = $da;
}
ksort($ordered);
Concatenate the two fields when creating your new array:
foreach ($data as $da) {
$result[$da['Number'] . '.' . $da['Location']] = $da;
}
$result = array_values($result); // Turn it back into indexed array
Try this..
<?php
$array = array(
0 => array('Number'=>'L1','Location'=>'Location-A','Qty'=>'1'),
1 => array('Number'=>'L1','Location'=>'Location-B','Qty'=>'5'),
2 => array('Number'=>'L1','Location'=>'Location-B','Qty'=>'4'),
3 => array('Number'=>'L2','Location'=>'Location-B','Qty'=>'5'),
);
$output = array_values(array_intersect_key($array,array_unique(array_map(function($arrayval) {
return $arrayval['Number'] . '.' .$arrayval['Location'];
}, $array))
));
print_r($output);
Output
Array ( [0] => Array ( [Number] => L1 [Location] => Location-A [Qty] => 1 )
[1] => Array ( [Number] => L1 [Location] => Location-B [Qty] => 5 )
[2] => Array ( [Number] => L2 [Location] => Location-B [Qty] => 5 ) )
Try this:
function array_unique_c($array, Closure $comparer) {
$result = array();
for($i = 0; $i < count($array); $i++) {
$duplicates = false;
for($n = $i + 1; $n < count($array); $n++) {
if ($comparer($array[$i], $array[$n])) {
$duplicates = true;
break;
}
}
if(!$duplicates) {
$result[] = $array[$i];
}
}
return $result;
}
Usage:
$uniqueArray = array_unique_c($a, function ($itemA, $itemB) {
return $itemA['Number'] == $itemB['Number'] && $itemA['Location'] == $itemB['Location'];
});
Output:
array(3) {
[0] => array(3) {
["Number"] => string(2) "L1"
["Location"] => string(10) "Location-A"
["Qty"] => string(1) "1"
}
[1] => array(3) {
["Number"]=> string(2) "L1"
["Location"]=> string(10) "Location-B"
["Qty"]=> string(1) "4"
}
[2]=> array(3) {
["Number"]=> string(2) "L2"
["Location"]=> string(10) "Location-B"
["Qty"]=> string(1) "5"
}
}
Easy way to do this job:
$data = [
["Number"=> "L1","Location"=> "Location-A","Qty"=>"1"],
["Number"=> "L2","Location"=> "Location-B","Qty"=>"6"],
["Number"=> "L3","Location"=> "Location-A","Qty"=>"8"],
["Number"=> "L2","Location"=> "Location-B","Qty"=>"5"],
["Number"=> "L3","Location"=> "Location-A","Qty"=>"2"],
["Number"=> "L1","Location"=> "Location-B","Qty"=>"4"],
["Number"=> "L1","Location"=> "Location-B","Qty"=>"1"],
["Number"=> "L2","Location"=> "Location-B","Qty"=>"3"],
];
foreach ($data as $k=>$v) {
$arr[md5($v['Number'].$v['Location'])] = $v;
}
$result = array_values($arr); //can be omitted
As you can see $arr is equal $result and you can ommit array_values() func
The question might be silly. But I am stucked in here. :( I am getting all of my database value as an object in controller.
This is how I am fetching database value:
$points = $this->CI->modelgraph->get($user_id);
It is getting all of the data corresponding to that user. This is my sample database table from where I am fetching data:
id user_id b_value h_value date r_value
1 24 330 6.2 10.11.2014 90
2 25 334 6.2 10.11.2014 92
This is static data, phpgraphlib provide in the tutorial.
$data = array("1" => .0032, "2" => .0028, "3" => .0021, "4" => .0033,
"5" => .0034, "6" => .0031, "7" => .0036, "8" => .0027, "9" => .0024,
"10" => .0021, "11" => .0026, "12" => .0024, "13" => .0036,
"14" => .0028, "15" => .0025);
I need to extract the fetched data in this manner:
$data = array("h_value" => b_value,);
How could achieve this? What will be the logic? Any help would be really appreciable.
Here is my approach.. but also not complete.. What I am doing wrong?
$total=count($points);
$i=1;
$dataArray=array();
while($i <= $total) {
foreach($points as $value) {
//echo $value -> h_value;
$field = $value -> h_value;
$labels = $value -> b_value;
$dataArray[$i][$field ] = $labels;
$i++;
}
}
When I var_dump($dataArray); Its giving me this output:
array(11) { [1]=> array(1) { ["6.6"]=> string(3) "358" } [2]=> array(1) { ["7.4"]=> string(3) "201" } [3]=> array(1) { ["6.5"]=> string(3) "144" } [4]=> array(1) { ["6.5"]=> string(3) "112" } [5]=> array(1) { ["6.2"]=> string(3) "144" } [6]=> array(1) { ["6.2"]=> string(3) "185" } [7]=> array(1) { ["7.0"]=> string(3) "176" } [8]=> array(1) { ["7.5"]=> string(3) "234" } [9]=> array(1) { ["6.5"]=> string(3) "365" } [10]=> array(1) { ["6.2"]=> string(3) "110" } [11]=> array(1) { ["4.2"]=> string(3) "100" } }
But When I var_dump($data); Its giving this:
array(15) { [1]=> float(0.0032) [2]=> float(0.0028) [3]=> float(0.0021) [4]=> float(0.0033) [5]=> float(0.0034) [6]=> float(0.0031) [7]=> float(0.0036) [8]=> float(0.0027) [9]=> float(0.0024) [10]=> float(0.0021) [11]=> float(0.0026) [12]=> float(0.0024) [13]=> float(0.0036) [14]=> float(0.0028) [15]=> float(0.0025) }
Its clearly visible I have messed up . Where is the wrong ?
Here is the output I print_r($points); Its giving this:
Array ( [0] => stdClass Object ( [id] => 12 [user_id] => 24 [b_value] => 358 [h_value] => 6.6 [rec_date] => 2014-09-19 [rec_time] => [h_value] => 1[date_added] => 2012-09-19 16:38:05 [date_modified] => 0000-00-00 00:00:00 ) [1] ..........
Please see below code.
It is self-explanatory.
Replace your values accordingly.
<?php
function modelFunction($user_id) {
$this->db->select('h_value, b_value');
$this->db->from('YOUR_TABLE_NAME');
$this->db->where('user_id', $user_id);
$query = $this->db->get();
$arr = array();
if ($query->num_rows()) {
$i=0;
foreach ($query->result_array() as $row) {
extract($row);
$arr[$i][$h_value] = $b_value;
++$i;
}
}
}
?>
Controller:
<?php
$points = $this->CI->modelFunction->get($user_id);
?>
Answer edited as per OP's request:
<?php
$dataArray = array();
for ($i=0 ; $i<= $total ; $i++) {
$value = $points[$i];
$field = $value->h_value;
$labels = $value->b_value;
$dataArray[$i][$field ] = $labels;
$i++;
}
?>
$new_array = array();
foreach($points as $point){
$new_array[] = array(
'id' => $point->id,
'user_id' => $point->user_id
);
}
Nice little helper function:
function object_to_array($data)
{
if (is_object($data)) {
$data = get_object_vars($data);
}
if (is_array($data)) {
return array_map(__FUNCTION__, $data);
}
else {
return $data;
}
}
example usage:
$data['points'] = $this->CI->modelgraph->get($user_id);
$data['points'] = object_to_array($data['points']);
I have an array like:
print_r($arr);
array(2) {
["'type'"]=>
array(3) {
[0]=>
string(17) "tell" // <----
[1]=>
string(6) "mobile" // <----
[2]=>
string(6) "address" // <----
}
["'value'"]=>
array(3) {
[0]=>
string(11) "+00.0000000" // tell
[1]=>
string(11) "12345678" // mobile
[2]=>
string(11) "Blah SQ." // address
}
}
I want a final string like:
tell = +00.0000000<br />mobile = 12345678<br />address = Blah SQ.
Now it's been more than an hour I'm struggling with this but no results yet, anyone could help me with this? I would appreciate anykind of help.
Thanks
=======================================
What I have tried:
$arr is an array so I did:
foreach($arr as $values){
// here also $values is an array, so I needed another foreach to access to items:
$i = 0;
foreach($values as $items){
// now making the final output
#$output.= $items['type'][$i] . '=' . $items['value'][$i] . '<br />';
$i++;
}
}
I'd go for array_combine(). Basically it does what you request:
$yourArray = [
"type" => ["tell", "mobile", "address"],
"value" => ["+00.0000000", "12345678", "Blah SQ."]
];
$combined = array_combine($yourArray["type"], $yourArray["value"]);
will be
$combined = [
"tell" =>"+00.0000000",
"mobile" =>"12345678",
"address" =>"Blah SQ."
];
Lastly, you can iterate through that array and then join the values:
$finalArray=array();
foreach($combined as $type=>$value)
$finalArray[]="$type=$value";
$string = join("<br/>", $finalArray); // Will output tell=+00.000000<br/>mobile=12345678<br/>address=Blah SQ.
It's not the fastest method but you'll learn quite a bit about arrays.
EDIT (using array_combine by #Dencker)
foreach($arr as $values) {
// here also $values is an array, so I needed another foreach to access to items:
$v = array_combine($values["'type'"], $values["'value'"]);
foreach($v as $key => $val) {
// now making the final output
$output.= $key . '=' . $val . '<br />';
}
}
Try this
$arr = array(
array(
"'type'" => array('tell', 'mobile', 'address'),
"'value'" => array('+00000', '123123', 'foo')
),
array(
"'type'" => array('tell', 'mobile', 'address'),
"'value'" => array('+10000', '123123', 'bar')
),
array(
"'type'" => array('tell', 'mobile', 'address'),
"'value'" => array('+20000', '123123', 'foobar')
),
);
var_dump($arr);
$output = '';
foreach($arr as $values) {
// here also $values is an array, so I needed another foreach to access to items:
$i = 0;
foreach($values as $items) {
// now making the final output
$output.= $values["'type'"][$i] . '=' . $values["'value'"][$i] . '<br />';
$i++;
}
}
echo $output;
You were referencing the other array in the second loop.
=============================================================
EDIT:
var_dump($arr);
array(3) {
[0]=> array(2) {
["type"]=> array(3) {
[0]=> string(4) "tell"
[1]=> string(6) "mobile"
[2]=> string(7) "address"
}
["value"]=> array(3) {
[0]=> string(6) "+00000"
[1]=> string(6) "123123"
[2]=> string(3) "foo"
}
}
[1]=> array(2) {
["type"]=> array(3) {
[0]=> string(4) "tell"
[1]=> string(6) "mobile"
[2]=> string(7) "address"
}
["value"]=> array(3) {
[0]=> string(6) "+10000"
[1]=> string(6) "123123"
[2]=> string(3) "bar"
}
}
[2]=> array(2) {
["type"]=> array(3) {
[0]=> string(4) "tell"
[1]=> string(6) "mobile"
[2]=> string(7) "address"
}
["value"]=> array(3) {
[0]=> string(6) "+20000"
[1]=> string(6) "123123"
[2]=> string(6) "foobar"
}
}
}
OUTPUT:
tell=+00000
mobile=123123
tell=+10000
mobile=123123
tell=+20000
mobile=123123
I need to split the following
$str = 'min(5,6,7,88),email'
$str= 'min(5,6,7,88),!email,max(6,5),alpha_numeric,required'//other possibilities
so it returns an array like so:
array(
[0]=>array(
[0]=>'min',
[1]=>array(5,6,7,88)
)
[1]=>array(
[0]=>'email'
)
)
is this possible ? btw email and min could be anything really , aswell as 5 6 7 88
I think preg_match is best suited for this particular case. However, preg_match alone cannot format the output as you want it.
preg_match('/(\w+)\(([0-9,]+)\),(\w+)+/', $str, $values);
$output = array(
array($values[1], explode(',', $values[2])),
array($values[3]),
);
Given the following:
$test = "min(5,6,7,88),email";
$_ = null;
if (preg_match('/^(?<first>\w+)\((?<array>(?:[0-9]+\x2C*)+)\)\x2C(?<last>\w+)$/',$test,$_))
{
$result = Array(
Array($_['first'],explode(',',$_['array'])),
Array($_['last'])
);
print_r($result);
}
Renders the following result:
Array
(
[0] => Array
(
[0] => min
[1] => Array
(
[0] => 5
[1] => 6
[2] => 7
[3] => 88
)
)
[1] => Array
(
[0] => email
)
)
function parse($str) {
$str = str_replace(array('(',')'),"0x00",$str);
$strArray = explode("0x00",$str);
$tokens = array();
$tokenRef = 0;
foreach($strArray as $tokenID => $tokenValue) {
if (($tokenID % 2) == 1) {
--$tokenRef;
$tokens[$tokenRef++][1] = '('.$tokenValue.')';
} else {
$tokenList = explode(",",$tokenValue);
foreach($tokenList as $token) {
if ($token != '') {
$tokens[$tokenRef++][0] = $token;
}
}
}
}
return $tokens;
}
$str = 'min(5,6,7,88),email';
$split = parse($str);
echo '<pre>';
var_dump($split);
echo '</pre>';
echo '<br />';
$str = 'min(5,6,7,88),!email,max(6,5),alpha_numeric,required';
$split = parse($str);
echo '<pre>';
var_dump($split);
echo '</pre>';
echo '<br />';
Gives
array(2) {
[0]=>
array(2) {
[0]=>
string(3) "min"
[1]=>
string(10) "(5,6,7,88)"
}
[1]=>
array(1) {
[0]=>
string(5) "email"
}
}
and
array(5) {
[0]=>
array(2) {
[0]=>
string(3) "min"
[1]=>
string(10) "(5,6,7,88)"
}
[1]=>
array(1) {
[0]=>
string(6) "!email"
}
[2]=>
array(2) {
[0]=>
string(3) "max"
[1]=>
string(5) "(6,5)"
}
[3]=>
array(1) {
[0]=>
string(13) "alpha_numeric"
}
[4]=>
array(1) {
[0]=>
string(8) "required"
}
}