change key of the multi-array - php

Have an array:
$a =array[
"param1"=>[]
"param2"=>[]
"param3"=>[]
]
function def($param){
return $param.date();
}
want return a new array
$a =array[
def(param1)=>[]
def(param2)=>[]
def(param3)=>[]
]
anybody know how to do this?

Do you mean something like this?
This is a pretty lengthy (and dirty) suggestion and there's probably a better way using one of PHP's array methods, but here goes:
$array = array('123' => 'should be 6', '14' => 'should be 5', '12' => 'should be 3');
$new_array = array();
foreach ($array as $key => $val) {
$key_exp = str_split($key);
$new_key = 0;
foreach ($key_exp as $key_int) $new_key += $key_int;
$new_array[$new_key] = $val;
}
Gives this output as expected:
array(3) {
[6]=>
string(11) "should be 6"
[5]=>
string(11) "should be 5"
[3]=>
string(11) "should be 3"
}
Note that you may, and probably will, run into key collisions using this method.

Like so:
$out_array = array_fill_keys(array_map(function($in) {
// do stuff you need
return $out;
}, array_keys($in_array)), array());

Related

Vardump to single variables in php

Lets say I have a function like this:
foreach ($links as $link) {
var_dump($link->nodeValue);}
And the output looks like this:
string(59) "I was "not" scared" string(32) "Hold my beer!" string(60) "üöä possible episode4" string(43)
So now I want the text behind the string() so I have its like this:
echo $first; // I was "not" scared
echo $second; // Hold my beer!
echo $third; // I hate strings3000
Only way I can think of is fetch var_dump with ob_start(); and substr is somehow...
(If you're on >= 7.0) the following should work for you:
$links = [
(object)['nodeValue' => 'i was "not" scared'],
(object)['nodeValue' => 'hold my beer'],
]; // just as an input example
list($first, $second) = array_column($links, 'nodeValue');
If on < 7.0 array_column can't pluck properties of objects so you'd have to gather it yourself with e.g.:
$values = array_map(function($node) {return $node->nodeValue;}, $links);
list($first, $second) = $values;
if I have correctly understood the question you can make a simple function similar to this :
function dumper($array){
foreach($array as $value){
foreach($value as $x){
echo gettype($x)."(".strlen($x).")". "\n";
echo $x. "\n";
}
}
}
and then :
$array = [
(object)['nodeValue' => 'sadasdadasd'],
(object)['nodeValue' => 'asdasdasdasdasd'],
(object)['nodeValue' => 'sadasdadasd'],
(object)['nodeValue' => 'asdasdasdasdasd'],
];
dumper($array);
That outputs:
string(11)
sadasdadasd
string(15)
asdasdasdasdasd
string(11)
sadasdadasd
string(15)
asdasdasdasdasd

Whether there is a function to create assoc array from other array values?

I have an array with two values, something like ((id, value), (id, value), (id, value)) and i need to do the array like id => value so i wondering is there some functions in php for this kind of job or i need to write my own. Just don't want to reinvent the wheel....
UPDATE
array(2) {
[0]=>
array(2) {
["site_id"]=>
string(3) "12"
["timestamp"]=>
string(19) "2014-01-09 08:48:40"
}
[1]=>
array(2) {
["site_id"]=>
string(3) "13"
["timestamp"]=>
string(19) "2014-02-07 14:27:57"
}
}
Some HOFs in php, just for fun:
$data = array(
array('foo', 'bar'),
array('baz', '42'),
);
$ithIx = function($ix) {
return function($item) use($ix) {
return $item[$ix];
};
};
$combined = array_combine(
array_map($ithIx(0), $data),
array_map($ithIx(1), $data)
);
var_dump($combined);
Online demo: http://ideone.com/jIsgpL
For the ones who cannot see beauty in functional style - here is some boring foreach:
$combined = array();
foreach ($data as $val) {
$combined[$val[0]] = $val[1];
}
Another solution (semi-boring):
$a = array(
array(1, 'Hello'),
array(2, 'World')
);
$a = array_combine(array_column($a, 0), array_column($a, 1));
(if PHP < 5.5)
function array_column($array, $column)
{
return array_map(function($e) use ($column) {return $e[$column];}, $array);
}

PHP array remove all arrays under keyword if found

I have 30 lines of text and explode into arrays separate by "\n". the result as follows:
[1]=> string(121) "In recent years, the rapid growth"
[2]=> string(139) "information technology has strongly enhanced computer systems"
[3]=> string(89) "both in terms of computational and networking capabilities"
[4]=> string(103) "-------------------------"
[5]=> string(103) "these novel distributed computing scenarios"
.
.
[30]=> string(103) "these computer safety applications. end"
in this case, i need to remove all arrays below "-------------" and produce output as follows:
[1]=> string(121) "In recent years, the rapid growth"
[2]=> string(139) "information technology has strongly enhanced computer systems"
[3]=> string(89) "both in terms of computational and networking capabilities"
any idea how to do this? thanks.
solution of the problem by Michael
$i = 0;
$new_arr = array();
while ($array[$i] != "-------------------------") {
// Append lines onto the new array until the delimiter is found
$new_arr[] = $array[$i];
$i++;
}
print_r($new_arr);
Best solution:
Use array_search() and then truncate the array with array_splice():
$key = array_search("-------------------------", $array);
array_splice($array, $key);
Obvious solution:
You can loop over it copying the output to a new array. First example that comes to mind:
$i = 0;
$new_arr = array();
while ($array[$i] != "-------------------------") {
// Append lines onto the new array until the delimiter is found
$new_arr[] = $array[$i];
$i++;
}
print_r($new_arr);
for example
function getMyArray( $array ){
$myArray = array();
foreach( $array as $item ){
if ( $item == '-------------------------' ){ return $myArray; }
$myArray[] = $line;
}
return $myArray'
}
array_search
and unset
you can also use array_slice
You can use array_search to find the key of where its located.
from PHP.net:
<?php
$array = array(0 => 'blue', 1 => 'red', 2 => 'green', 3 => 'red');
$key = array_search('green', $array); // $key = 2;
?>
Once you have the key, you could do:
<?php
while($key < count($array) )
{
$array = unset($array[$key]);
$key++;
}
?>
foreach($array as $key => $value)
{
if($value == '-------------')
break;
else
$new_array[$key]=$value;
}

Using array to create WHERE condition

My function receives a array as parameter:
array(6) {
[0]=>
string(7) "usuario"
[1]=>
string(4) "john"
[2]=>
string(5) "senha"
[3]=>
string(40) "7c4a8d09ca3762af61e59520943dc26494f8941b"
[4]=>
string(9) "pessoa_id"
[5]=>
string(1) "2"
}
What I need:
SELECT * FROM (`funcionarios`) WHERE `usuario` = 'john' AND `senha` = '7c4a8d09ca3762af61e59520943dc26494f8941b' AND `pessoa_id` = '2'
I need to create a WHERE with it, I'm using CodeIgniter and I came to this stupid but working solution:
foreach($params as $x) {
if($pos%2==0)
$chave = $x;
else
$valor = $x;
$pos++;
if($pos%2==0)
$this->db->where($chave, $valor);
}
I'm trying to find something more user friendly because there will be another person using this code.
What is the best way to do this?
I think this it the best way if you can't change that array. IF you can, do so now, because it's really inelegant
$data = array(
"usuario" => "john",
"senha" => "7c4a8d09ca3762af61e59520943dc26494f8941b",
"pessoa_id" => 2
);
foreach($params as $x => $y) {
$this->db->where($x, $y);
}
If you can change the format of the array, just use an associative array. For example:
array(
"usuario" => "john" //etc.
);
Then you can take advantage of the key function in PHP to avoid your even index checking in the loop, or even change your loop to:
foreach ($params as $key => $value)
$query = "SELECT * FROM `funcionarios` WHERE ";
$wheres = array();
foreach ($paramas as $key => $val) {
$wheres[] = "`$key`='$val'";
}
$query .= implode(' AND ', $wheres); // $query is now "SELECT * FROM `funcionarios` WHERE `myKey`='myValue' AND `otherkey`='otherval'";
That should work
Generate a new proper associative array from the original. Then it's much easier.
$arr = array("key1", "value1", "key2", "value2", "key3", "value3");
$newArr = array();
for ($i = 0; $i < count($arr); $i += 2) {
$newArr[$arr[$i]] = $arr[$i + 1];
}
Then using foreach you can build your query.

Simple PHP Recursion Test Failing

I am attempting a basic recursion to create multi-dimensional arrays based on the values of an inputed array.
The recursion works by checking for a value we shall call it "recursion" to start the loop and looks for another value we'll call it "stop_recursion" to end.
Basically taking this array
array('One', 'Two', 'recursion', 'Three', 'Four', 'Five', 'stop_recursion', 'Six', 'Seven')
And making this array
array('One', 'Two', array('Three', 'Four', 'Five'), 'Six', 'Seven')
The code I have for it so far is as follows
function testRecrusion($array, $child = false)
{
$return = array();
foreach ($array as $key => $value) {
if ($value == 'recursion') {
unset($array[$key]);
$new = testRecrusion($array, true);
$array = $new['array'];
$return[] = $new['return'];
} else {
if ($value == 'stop_recursion') {
unset($array[$key]);
if ($child) {
return array('return' => $return, 'array' => $array);
}
} else {
unset($array[$key]);
$return[] = $value;
}
}
}
return $return;
}
But the output from that is
Array
(
[0] => One
[1] => Two
[2] => Array
(
[0] => Three
[1] => Four
[2] => Five
)
[3] => Three
[4] => Four
[5] => Five
[6] => Six
[7] => Seven
)
I guess the real question is...will an array values continuously loop through the first values given from the initial call or once the new array is returned and set will it loop through that new array. I know the answer is basically right here saying that yes it will continue the old array value, but shouldn't this work vice-versa?
Any help will be appreciated :)
------------ edit -------------------
I might as well add that while I can perform this action using a much simpler method, this needs to be recursively checked since this will be ported to a string parser that could have a infinite number of child arrays.
When you return inside the recursion, you need to return both the inner array and the index from which to continue searching for elements so that you don't look at the same element twice. Try this instead:
function testRecursionImpl($array, $i)
{
$return = array();
for (; $i < sizeof($array); ++$i) {
if ($array[$i] == 'recursion') {
$new = testRecursionImpl($array, $i + 1);
$return[] = $new[0];
$i = $new[1];
} else if ($array[$i] == 'stop_recursion') {
return array($return, $i);
} else {
$return[] = $array[$i];
}
}
return array($return, $i);
}
function testRecursion($array)
{
$result = testRecursionImpl($array, 0);
return $result[0];
}
The problem you have in the code above is that you correctly detect when you should call this function recursively but once it finishes running and you append the results to output array you just pick next element (which is the first element that recursive call will get) and append it to output array. What you probably want to do is when you detect that you should run your function recursively you should skip all other characters until you find your stop word (stop_recursion). Obviously the problem will become harder if you allow multi-level recursion then you may need to even skip some stopwords because they could be from the different level call.
Still I don't know why you want such a feature. Maybe you would explain what are you trying to achieve. I'm pretty sure there's another, simpler way of doing it.
Rather than helping with your homework, I would suggest you start with getting rid of this line:
foreach ($array as $key => $value) {
You should just pass in your array, and check for being at the end of the array, since it can't really be infinite, to know when you are done.
Let me give it a try
function testRecursion($arr){
$return = array();
$recurlevel = 0;
foreach ($arr as $v) {
if($v == 'stop_recursion'){
$recurlevel--;
}
if($recurlevel == 0){
if(isset($current)){
$return[] = testRecursion($current);
unset($current);
}else{
if($v != 'recursion'){
$return[] = $v;
}
}
}else{
if(!isset($current)){
$current = array();
}
$current[] = $v;
}
if($v == 'recursion'){
$recurlevel++;
}
}
return $return;
}
Alright nicely done. This will help even if the recursion and stop_recursion are nested in another. See example:
code.php:
<pre><?php
function testRecursion($arr){
$return = array();
$recurlevel = 0;
foreach ($arr as $v) {
if($v == 'stop_recursion'){
$recurlevel--;
}
if($recurlevel == 0){
if(isset($current)){
$return[] = testRecursion($current);
unset($current);
}else{
if($v != 'recursion'){
$return[] = $v;
}
}
}else{
if(!isset($current)){
$current = array();
}
$current[] = $v;
}
if($v == 'recursion'){
$recurlevel++;
}
}
return $return;
}
$a = array('One', 'Two', 'recursion', 'Three', 'recursion', 'Four' , 'stop_recursion', 'Five', 'stop_recursion', 'Six', 'Seven');
var_dump(testRecursion($a));
?>
Browser output:
array(5) {
[0]=>
string(3) "One"
[1]=>
string(3) "Two"
[2]=>
array(3) {
[0]=>
string(5) "Three"
[1]=>
array(1) {
[0]=>
string(4) "Four"
}
[2]=>
string(4) "Five"
}
[3]=>
string(3) "Six"
[4]=>
string(5) "Seven"
}
Since your question for the recursive solution has already been answered ...might I offer a stack-based solution?
$x = array('a', 'b', 'recursion', 'cI', 'cII', 'cIII', 'recursion', 'cIV1', 'cIV2', 'cIV2', 'stop_recursion', 'stop_recursion', 'd', 'e');
$result = array();
$stack = array(&$result);
foreach($x as $e) {
if ( 'recursion'===$e ) {
array_unshift($stack, array());
$stack[1][] = &$stack[0];
}
else if ( 'stop_recursion'===$e ) {
array_shift($stack);
}
else {
$stack[0][] = $e;
}
}
var_dump($result);
prints
array(5) {
[0]=>
string(1) "a"
[1]=>
string(1) "b"
[2]=>
array(4) {
[0]=>
string(2) "cI"
[1]=>
string(3) "cII"
[2]=>
string(4) "cIII"
[3]=>
array(3) {
[0]=>
string(4) "cIV1"
[1]=>
string(4) "cIV2"
[2]=>
string(4) "cIV2"
}
}
[3]=>
string(3) "d"
[4]=>
string(5) "e"
}

Categories