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.
Related
I have arrays, I don't know how to fix
I already try array_push, array_combine, array_merge, but still nothing.
$distance = array(3) {
[0]=>
float(2.2)
[1]=>
float(1.1)
[2]=>
float(3.9)
}
$getID = array(3) {
[0]=>
string(1) "B"
[1]=>
string(1) "C"
[2]=>
string(1) "F"
}
I want to
array(3) {
[0]=> ["B", 2.2]
[1]=> ["C", 1.1]
[2]=> ["F", 3.9]
}
this is my code
function mergeArray($distance, $getID)
{
$mergeArray = array();
for ($i = 0; $i < count($distance); $i++) {
$mergeArray[] = array_splice($getID, $distance[$i]);
}
return $mergeArray;
}
Edited
help me please thx
You don't need "array_combine()", "array_slice()" or similar. Just iterate through the data and create a new one:
$a = [2.2, 1.1, 3.9];
$b = ["B", "C", "F"];
$new = [];
foreach ($a as $index => $value) {
$new[] = [
$b[$index], // Fetch the value with the same index from the other array
$value
];
}
Demo: https://3v4l.org/oseSV
You can use array_map to iterate over two arrays simultaneously and produce a new array:
$distance = array(3) {
[0]=>
float(2.2)
[1]=>
float(1.1)
[2]=>
float(3.9)
}
$getID = array(3) {
[0]=>
string(1) "B"
[1]=>
string(1) "C"
[2]=>
string(1) "F"
}
$output = array_map(function ($d, $id) {
return [$id, $d];
}, $distance, $getID);
Note that this code assumes that both arrays have the same length.
Offtopic:
A little advice about your code: always name your variable with something that allows you to know what's inside it, using correct plural too:
Your $distance variable contains an array off distances, so it nsme should be in plural.
Your $getID is not a function, so it should not be called get, but just $Ids instead.
$distance = [ 2.2, 1.1, 3.9 ];
$getID = [ "B", "C", "F" ];
$result = array_map(fn(string $id, float $distance) => [ $id, $distance ], $getID, $distance);
print_r($result);
For your current code to work you have to:
pass both elements to array_splice function as an array
pass the offset of where the function need to replace the value
as well as the number of how many elements should be removed
You should not reassign $mergeArray because array_splice work with pointer
Checkout the docs for more!
function mergeArray($distance, $getID)
{
$mergeArray = [];
for ($i = 0; $i < count($distance); $i++) {
array_splice($mergeArray,$i,1, [[
$distance[$i],
$getID[$i]
]]);
}
return $mergeArray;
}
however a better approach is to do as in M. Eriksson's ansewar.
I have a database with multiple records. It is structured like this:
["data"]=>
array(5) {
[1]=>
[2]=>
array(11) {
[0]=>
string(1) "0"
[1]=>
string(8) "25000000"
[2]=>
string(3) "day"
[3]=>
string(5) "0.00%"
[4]=>
string(9) "404049904"
[5]=>
string(1) "0"
[6]=>
string(5) "0.00%"
[7]=>
string(1) "0"
[8]=>
string(1) "0"
[9]=>
string(1) "0"
[10]=>
string(3) "0.0"
}
I need to fetch the 8th record and I do this by using
public static function($data)
{
$array = [];
$path = $data->data[2];
foreach($path as $key => $item)
if($key > 1)
{
$array[] = [$item->data[8]];
}
return json_encode($array);
}
This foreach takes all the 8th values from the array but I need to display a single number which is the average of all the 8th values. How can I do this?
Once you've got your array containing all your data, simple sum the array and then divide by the size of the array.. something along these lines
$average = (array_sum($array) / count($array));
Of course you may want to check for count($array) being 0;
Because you put your value into a new array, you can not use array_sum to sum the values, so you should store it.
$sum = 0;
foreach($path as $key => $item)
if($key > 1) {
$array[] = [$item->data[8]];
$sum += $item->data[8];
}
}
$avg = ($sum / count($array); //the average
var_dump($avg);
If is it possible, just put it as a value:
$array[] = $item->data[8]; //no wrapping []
In this case, you can use $avg = array_sum($array) / count($array);
if (count($array)>0){
$avg = array_sum($array) / count($array);
}
I would personally do those calculations in the database before the data gets to your PHP script itself. See AVG().
If you can't for some reason use that I would output those values into a flat array and then just calculate the average. So something like :
function getAverage($data) {
$flatArray = array();
foreach ($data as $row) {
if (!empty($row->8)) {
$flatArray[] = $row->8;
}
}
return (array_sum($flatArray)/count($flatArray));
}
EDIT: Moved to Object traversing on the data row, sorry, missed that initially and thought it was an array in all the nests.
Since you have a loop within your static Method; why not do the calculation therein and return it or add it to the JSON Data if You need your Data in JSON Format? Here's what's implied by the above:
public static function getAverageSum($data) {
$array = [];
$path = $data->data[2];
$sumTotal = 0.00; //<== YOU COULD JUST SUM IT DIRECTLY WITHOUT USING AN ARRAY
foreach($path as $key => $item) {
if ($key > 1) {
$array[] = $item->data[8];
$sumTotal += floatval($item->data[8]);
}
}
// IF YOU ARE ONLY INTERESTED IN THE AVERAGE SUM YOU COULD EVEN ADD IT IT TO THE $array AS AN EXTRA KEY
// LIKE SO:
$arrLen = count($array);
$array['avgSum'] = $sumTotal/$arrLen;
// IF YOU NEED YOUR DATA IN JSON... THEN RETURN THE JSON ENCODED DATA WITH SUM AS PART OF THE DATA.
// YOU'D HAVE NO NEED FOR array_sum() SINCE YOU DID YOUR PREP-WORK ALREADY...
return json_encode($array);
// ALTERNATIVELY; IF ALL YOU NEED IS JUST THE AVERAGE SUM; YOU COULD AS WELL DIRECTLY RETURN $sumTotal/$arrLen
return ($sumTotal/$arrLen);
}
This question already has answers here:
Is there a function to extract a 'column' from an array in PHP?
(15 answers)
Closed 6 months ago.
I have an array
array(5) {
[0]=>
array(1) {
["id"]=>
string(1) "5"
}
[1]=>
array(1) {
["id"]=>
string(1) "6"
}
[2]=>
array(1) {
["id"]=>
string(1) "7"
}
[3]=>
array(1) {
["id"]=>
string(1) "8"
}
[4]=>
array(1) {
["id"]=>
string(1) "9"
}
}
I wan to make my array like:
$registrationIDs = array( "5","6","7","8","9");
I am trying this code but not working
$results = array();
foreach($result as $inner) {
$results[key($inner)] = current($inner);
}
How do I effeciently transform arrays like this
Try with array_map.
$results = array_map (function ($e) { return $e['id']; }, $inner);
http://php.net/manual/en/function.array-map.php
By the way, if you still want to do it your way, try this form of foreach :
$results = array ();
foreach ($inner as $key => $value)
$results[$key] = $value['id'];
$array = [['id'=>1],['id'=>2],['id'=>3],['id'=>4],['id'=>5],];
$result = call_user_func_array('array_merge_recursive', $array);
var_dump($result['id']);
//array(5) {
// [0] =>
// int(1)
// [1] =>
// int(2)
// [2] =>
// int(3)
// [3] =>
// int(4)
// [4] =>
// int(5)
//}
Ok, I saw a lot of answers, so I wondered what to better answer was.
<?php
$data = array ();
for ($i = 0; $i < 1000000; $i++)
$data[$i] = array ('id' => rand ());
$time0 = microtime (true);
// Niols (1)
$results = array_map (function ($e) { return $e['id']; }, $data);
$time1 = microtime (true);
// Niols (2)
$results = array ();
foreach ($data as $key => $value)
$results[$key] = $value['id'];
$time2 = microtime (true);
// User (1)
$it = new RecursiveIteratorIterator(new RecursiveArrayIterator($data));
$results = iterator_to_array($it, false);
$time3 = microtime (true);
// User (2)
$results = array();
foreach ($data as $datum)
$results = array_merge($results, $datum);
$time4 = microtime (true);
// sectus
$results = call_user_func_array('array_merge_recursive', $data);
$time5 = microtime (true);
// Pankaj katiyar and Ghost
$results = array_column($data, 'id');
$time6 = microtime (true);
var_dump ($time1-$time0);
var_dump ($time2-$time1);
var_dump ($time3-$time2);
var_dump ($time4-$time3);
var_dump ($time5-$time4);
var_dump ($time6-$time5);
On my computer, this outputs :
float(0.62708687782288)
float(0.35285401344299)
float(1.5429890155792)
float(0.7408618927002)
float(0.70525908470154)
float(0.15015292167664)
Conclusion :
array_column is ultra-efficient (but PHP 5.5+). Writing a simple foreach seems quite efficient too.
You can try with below code.
I think this is working fine.
Process 1:-
$it = new RecursiveIteratorIterator(new RecursiveArrayIterator($data));
$l = iterator_to_array($it, false);
var_dump($l); // one Dimensional
Process 2:-
Try with:
$input = array(/* your array*/);
$output = array();
foreach ( $input as $data ) {
$output = array_merge($output, $data);
}
Try this:
$array = array(/*your array*/);
$results = array();
foreach ($array as $value)
{
foreach($value as $innerValue)
{
$results[] = $innervalue;
}
}
I have an array of arrays that look like this:
array(40) {
[0]=>
array(2) {
["id"]=>
string(2) "ta"
["size"]=>
int(2)
[1]=>
array(2) {
["id"]=>
string(2) "tq"
["size"]=>
int(4)
....
I want to be able to get all the sizes in a way that I can do a query like this:
IN (2,4)
so... For each array, get the size key: IN (size,size,size...)
Thanks!
You could do something like this:-
$sizes = implode(',', array_map(function($v) { return $v['size']; }, $array));
Then just pass $sizes to your IN query
edit
In response to your comment below, you can use array_unique to remove duplicate sizes, eg:
$sizes = implode(',', array_unique(array_map(function($v) { return $v['size']; }, $array)));
Here you go:
$a = array("id"=>"ta","size"=>2);
$b = array("id"=>"tq","size"=>4);
$c = array($a,$b);
$in = array();
foreach ($c as $key=>$value) {
if(array_key_exists("size", $value)){
$in[] = $value["size"];
}
}
echo implode(",", $in);
$sizes = array();
foreach($array as $value) {
$sizes[] = $value['size'];
}
$query = implode(',', $sizes);
query ..." IN ($query) "..
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"
}