Most efficient way to replace empty values in an array - php

Is there a better way of doing this PHP code? What I'm doing is looping through the array and replacing the "title" field if it's blank.
if($result)
{
$count = 0;
foreach($result as $result_row)
{
if( !$result_row["title"] )
{
$result[$count]["title"] = "untitled";
}
$count++;
}
}
Where $result is an array with data like this:
Array
(
[0] => Array
(
[title] => sdsdsdsd
[body] => ssdsd
)
[1] => Array
(
[title] => sdssdsfds
[body] => sdsdsd
)
)
I'm not an experienced PHP developer, but I guess that the way I've proposed above isn't the most efficient?
Thanks

if($result) {
foreach($result as $index=>$result_row) {
if( !$result_row["title"] ) {
$result[$index]["title"] = "untitled";
}
}
}
You don't need to count it. It's efficient.

if ($result)
{
foreach($result as &$result_row)
{
if(!$result_row['title'])
{
$result_row['title'] = 'untitled';
}
}
}
Also, you may want to use something other than a boolean cast to check the existence of a title in case some young punk director releases a movie called 0.
You could do something like if (trim($result_row['title']) == '')

Mixing in a little more to #Luke's answer...
if($result) {
foreach($result as &$result_row) { // <--- Add & here
if($result_row['title'] == '') {
$result_row['title'] = 'untitled';
}
}
}
The key is the & before $result_row in the foreach statement. This make it a foreach by reference. Without that, the value of $result_row is a copy, not the original. Your loop will finish and do all the processing but it won't be kept.
The only way to get more efficient is to look at where the data comes from. If you're retrieving it from a database, could you potentially save each record with an "untitled" value as the default so you don't need to go back and put in the value later?

Another alternative could be json_encode + str_replace() and then json_decode():
$data = array
(
0 => array
(
'title' => '',
'body' => 'empty',
),
1 => array
(
'title' => 'set',
'body' => 'not-empty',
),
);
$data = json_encode($data); // [{"title":"","body":"empty"},{"title":"set","body":"not-empty"}]
$data = json_decode(str_replace('"title":""', '"title":"untitled"', $data), true);
As a one-liner:
$data = json_decode(str_replace('"title":""', '"title":"untitled"', json_encode($data)), true);
Output:
Array
(
[0] => Array
(
[title] => untitled
[body] => empty
)
[1] => Array
(
[title] => set
[body] => not-empty
)
)
I'm not sure if this is more efficient (I doubt it, but you can benchmark it), but at least it's a different way of doing the same and should work fine - you have to care about multi-dimensional arrays if you use the title index elsewhere thought.

Perhaps array_walk_recursive:
<?php
$myArr = array (array("title" => "sdsdsdsd", "body" => "ssdsd"),
array("title" => "", "body" => "sdsdsd") );
array_walk_recursive($myArr, "convertTitle");
var_dump($myArr);
function convertTitle(&$item, $key) {
if ($key=='title' && empty($item)) {$item = "untitled";}
}
?>

If you want sweet and short, try this one
$result = array(
array(
'title' => 'foo',
'body' => 'bar'
),
array(
'body' => 'baz'
),
array(
'body' => 'qux'
),
);
foreach($result as &$entry) if (empty($entry['title'])) {
$entry['title'] = 'no val';
}
var_dump($records);
the empty() will do the job, see the doc http://www.php.net/manual/en/function.empty.php

Related

Php array and json

help me to convert the following array in to json.
I tried to convert the array.
Array
(
[0] => Array
(
[c_code] => 200001
[itemname] => 303 10CAP
[c_pack_code] => PK0075
[c_web_img_link] =>
)
[1] => Array
(
[c_code] => 200005
[itemname] => 3P 4TAB
[c_pack_code] =>
[c_web_img_link] =>
)
)
current result for the following code is
public function searchOrder($idx, $data) {
if (!empty($data)) {
$result = OrderbukModel::func_get_searchlist($idx,$data);
if (!empty($result)) {
$resultArray[] = $result;
print_r(json_encode($result));
} else {
$resultArray[$idx] = ["Mysql returns empty result !"];
print_r(json_encode($resultArray));
exit;
}
}
}
now i got the result is like
[{"c_code":"200001","itemname":"303 10CAP","c_pack_code":"PK0075","c_web_img_link":""},{"c_code":"200005","itemname":"3P 4TAB","c_pack_code":"","c_web_img_link":""}]
But I need the result as follows
[{"c_code":"2000001","c_code":"200005"},
{"itemname":"303 10CAP","itemname":"3P 4TAB"},
{"c_pack_code":"PK0075","c_pack_code":""},
{"c_web_img_link":"","c_web_img_link":""}]
Example of how you can you make the json from array. Collect the data in two different array and after loop marge them and store the result in another array after that encode them.
Note: Your desired JSON is not a valid format, you can't use same index
for two data.
Online Example: https://3v4l.org/kdPDI
$arr = array(
array(
'c_code' => '200001',
'itemname' => '303 10CAP',
'c_pack_code' => 'PK0075',
'c_web_img_link' => ''
),
array(
'c_code' => '200005',
'itemname' => '3P 4TAB',
'c_pack_code' => '',
'c_web_img_link' => ''
)
);
$res1 = array();
$res2 = array();
foreach($arr as $val){
$res1['c_code'][] = $val['c_code'];
$res1['itemname'][] = $val['itemname'];
$res2['c_pack_code'][] = $val['c_pack_code'];
$res2['c_web_img_link'][] = $val['c_web_img_link'];
}
$out = array(array_merge($res1, $res2));
echo json_encode($out);

Searching for a value in an array using PHP

I have a list of users in my mongodb database, which can then follow each other -pretty standard. Using php I want to check if a specific user is following another user. My data looks like this.
array (
'_id' => ObjectId("56759157e1095db549d63af1"),
'username' => 'Joe',
'following' =>
array (
0 =>
array (
'username' => 'John',
),
1 =>
array (
'username' => 'Tom',
),
),
)
array (
'_id' => ObjectId("56759132e1095de042d63af4"),
'username' => 'Tom',
'following' =>
array (
0 =>
array (
'username' => 'Joe',
),
1 =>
array (
'username' => 'John',
),
2 =>
array (
'username' => 'Sam',
),
),
)
I want a query that will check if Joe is following Sam (which he's not) - so it would produce no results. However, if I was to query the database to check if Tom was following Sam, then it would produce a result to indicate he is (because he is). Do you know how I would do this in PHP? I've experimented with Foreach loops, but I haven't been able to get the results I want.
Make it by DB query, by php it will take more resources
Still if you want by php you can make it so
$following=false;
foreach($data as $v) if ($v['username'] == 'Joe') {
foreach($v['following'] as $v1) if (in_array('Sam', $v1)) {
$following=true;
break 2;
}
}
echo $following;
Such queries are best done in SQL, but if you insist on a PHP-based solution I would suggest to turn the data structure into items keyed by name. Once you have that it is a piece of cake to find relationships:
function organisePersons($data) {
$persons = array();
foreach($data as $person) {
$list = array();
foreach($person["following"] as $following) {
$list[$following["username"]] = $following["username"];
}
$person["following"] = $list;
$person["followedBy"] = array();
$persons[$person["username"]] = $person;
}
// link back to get all "followedBy":
// You can skip this block if you don't need "followedBy":
foreach ($persons as $person) {
foreach($person["following"] as $following) {
echo $person["username"] . " f. $following<br>";
if (!isset($persons[$following])) {
$persons[$following] = array(
"_id" => null, // unknown
"username" => $following,
"following" => array(),
"followedBy" => array()
);
}
$persons[$following]["followedBy"][] = $person["username"];
}
}
// return the new structure
return $persons;
}
So first call the function above with the data you have:
$persons = organisePersons($data);
And then you can write this:
if (isset($persons["Joe"]["following"]["Sam"])) {
echo "Joe is following Sam"; // not in output
};
if (isset($persons["Tom"]["following"]["Sam"])) {
echo "Tom is following Sam"; // in output
};
But also:
echo "Tom is following " . implode($persons["Tom"]["following"], ", ");
// Output: Tom is following Joe, John, Sam
And even the reverse question "Tom is followed by who?":
echo "Tom is followed by " . implode($persons["Tom"]["followedBy"], ", ");
// Output: Tom is followed by Joe

How to unset dynamically generated multidimensional array

I am trying to delete an array whereby one of its values..(time) meet a specific condition. \The code I'm currently working with looks like this:
foreach($_SESSION as $key) {
foreach($key['time'] as $keys=>$value){
if(condition){
unset($key);
}
}
}
The array looks like this.
Array
(
[form1] => Array
(
[hash] => lFfKBKiCTG6vOQDa8c7n
[time] => 1401067044
)
[form5] => Array
(
[hash] => TTmLVODDEkI1NrRnAbfB
[time] => 1401063352
)
[form4] => Array
(
[hash] => XCVOvrGbhuqAZehBmwoD
[time] => 1401063352
)
I tried to adapt solutions from these pages but didn't work.
Remove element in multidimensional array and save
PHP - unset in a multidimensional array
PHP How to Unset Member of Multidimensional Array?
If you want to unset the values inside it, a simple single foreach will suffice. Consider this example:
$values = array(
'form1' => array('hash' => 'lFfKBKiCTG6vOQDa8c7n', 'time' => 1401067044),
'form5' => array('hash' => 'TTmLVODDEkI1NrRnAbfB', 'time' => 1401063352),
'form4' => array('hash' => 'XCVOvrGbhuqAZehBmwoD', 'time' => 1401063352),
);
$needle = 1401067044;
foreach($values as $key => &$value) {
if($value['time'] == $needle) {
// if you want to remove this key pair use this
unset($values[$key]['time']);
// if you just want to remove the value inside it
$value['time'] = null;
// if you want to remove all of this entirely
unset($values[$key]);
}
}
Fiddle
Unsetting in a for loop can lead to issues, its easier and better to use array_filter which is optimized for this kind of problem. Here is how to do it with your example. ideone running code
<?php
$ar = Array(
"form1" => Array
(
"hash" => 'lFfKBKiCTG6vOQDa8c7n',
"time" => '1401067044'
),
"form5" => Array
(
"hash" => 'TTmLVODDEkI1NrRnAbfB',
"time" => '1401063352'
),
"form4" => Array
(
"hash" => 'XCVOvrGbhuqAZehBmwoD',
"time" => '1401063352'
)
);
$condition = '1401067044';
$newArray = array_filter($ar, function($form) use ($condition) {
if (!isset($form['time'])) {
return true;
}
return $form['time'] != $condition;
});
var_export($newArray);
array_filter
Assuming your values are stored in $_SESSION
foreach($_SESSION as $key => $value) {
if(isset($value['time']) && $value['time'] < 1401063352) {
unset($_SESSION[$key]);
}
}
If you are storing your values in $_SESSION you may want to consider storing them in a subfield like $_SESSION['myForms'] so if you need to add other values to your session you can easily access only the values you need.
You need to do
unset($_SESSION[$key])
However as mentioned by Victory, array_filter is probably a better approach to this.

Find Value in Array

The following array is output from my db.
$this->db->select('code')->from('table');
$array = $this->db->get()->result_array();
//Output:
Array ( [0] => Array ( [code] => ASDF123 ) [1] => Array ( [code] => ASDF124 ) )
How can I find if a variable is contained in this array?
ie.
if(this_is_in_array($value, $array) == TRUE)...
What's the simplest way to to that with PHP?
I sincerely apologize for not wording this correctly the first time.
In case you wish to find the KEY of an array you would refer to the array_key_exists() method.
An example of this would be:
$array = array(
'key1' => 'value1',
'key2' => 'value2'
);
if ( array_key_exists( 'key2', $array ) )
return TRUE;
If you would however prefer to find the VALUE of an array, you would refer to the in_array() method. An example of this would be:
$array = array(
'key1' => 'value1',
'key2' => 'value2'
);
if ( in_array( 'value1', $array ) )
return TRUE;
Kevin:
foreach( $array as $key => $values )
{
if ( $values['code'] == 'ASD1234' )
{
// do something
}
}
make your array this:
$your_array = array('key1'=>'value1', 'key2'=>'value2');
then use this to see if the key exists in the array.
if (array_key_exists('key2', $your_array)) {
Unsure about what exactly you mean in your question, however, to answer your question title, you can use the array_key_exists() function to check if a given key or index exists within an array.
put your validation into the function
$input = 'ASDF123';
function check_input($input) {
$array = array(
0 => array('code' => 'ASDF123'),
1 => array('code' => 'ASDF124')
);
foreach ($array as $codes) {
if (in_array($input, $codes)) {
return true;
}
}
return false;
}
$needle = 'ASDF123';
$ary = Array(
Array('code' => 'ASDF123'),
Array('code' => 'ASDF124')
);
$_ = "return (\$a['code']='".addslashes($needle)."');";
if (count(array_filter($ary[0],create_function('$a',$_))) > 0)
//true
I THINK (only because you use code twice, so I assume that's not the search field--or it's a semantics issue). If it is semantics, as everyone else has already suggested, try array_key_exists.

Create array of hierarchical directories in PHP

I have the following code (I know that this code is not optimized but it's not for discussion):
function select_categories($cat_id)
{
$this->db = ORM::factory('category')
->where('parent', '=', $cat_id)
->find_all();
foreach ($this->db as $num => $category)
{
if($category->parent == 0)
{
$this->tmp[$category->parent][$category->id] = array();
}
else {
$this->tmp[$category->parent][$category->id] = array();
}
$this->select_categories($category->id);
}
return $this->tmp;
}
Function returns this array:
array(3) (
0 => array(2) (
1 => array(0)
2 => array(0)
)
2 => array(1) (
3 => array(0)
)
3 => array(2) (
4 => array(0)
5 => array(0)
)
)
But how should I change the code
else {
$this->tmp[$category->parent][$category->id] = array();
// ^^^^^^^^^^^^^^^^^^^^^^ (this bit)
}
To merge array[3] to array[2][3] for example (because array[3] is a subdirectory of array[2] and array[2] is a subdirectory of array[0][2]), so, I need to make this (when I don't know the level of subdirectories):
array (
0 => array (
1 => array
2 => array (
3 => array (
4 => array
5 => array
)
)
)
)
A long time ago I wrote some code to do this in PHP. It takes a list of entities (in your case, categories) and returns a structure where those entities are arranged in a tree. However, it uses associative arrays instead of objects; it assumes that the “parent” ID is stored in one of the associative array entries. I’m sure that you can adapt this to your needs.
function make_tree_structure ($nontree, $parent_field)
{
$parent_to_children = array();
$root_elements = array();
foreach ($nontree as $id => $elem) {
if (array_key_exists ($elem[$parent_field], $nontree))
$parent_to_children [ $elem[$parent_field] ][] = $id;
else
$root_elements[] = $id;
}
$result = array();
while (count ($root_elements)) {
$id = array_shift ($root_elements);
$result [ $id ] = make_tree_structure_recurse ($id, $parent_to_children, $nontree);
}
return $result;
}
function make_tree_structure_recurse ($id, &$parent_to_children, &$nontree)
{
$ret = $nontree [ $id ];
if (array_key_exists ($id, $parent_to_children)) {
$list_of_children = $parent_to_children [ $id ];
unset ($parent_to_children[$id]);
while (count ($list_of_children)) {
$child = array_shift ($list_of_children);
$ret['children'][$child] = make_tree_structure_recurse ($child, $parent_to_children, $nontree);
}
}
return $ret;
}
To see what this does, first try running it on a structure like this:
var $data = array (
0 => array('Name' => 'Kenny'),
1 => array('Name' => 'Lilo', 'Parent' => 0),
2 => array('Name' => 'Adrian', 'Parent' => 1)
3 => array('Name' => 'Mark', 'Parent' => 1)
);
var $tree = make_tree_structure($data, 'Parent');
If I’m not mistaken, you should get something like this out: (the “Parent” key would still be there, but I’m leaving it out for clarity)
array (
0 => array('Name' => 'Kenny', 'children' => array (
1 => array('Name' => 'Lilo', 'children' => array (
2 => array('Name' => 'Adrian')
3 => array('Name' => 'Mark')
)
)
)
Examine the code to see how it does this. Once you understand how this works, you can tweak it to work with your particular data.
Assuming you dont want any data/children tags in your array:
foreach ($this->db as $num => $category)
{
// save the data to the array
$this->tmp[$category->id] = array();
// save a reference to this item in the parent array
$this->tmp[$category->parent][$category->id] = &$this->tmp[$category->id];
$this->select_categories($category->id);
}
// the tree is at index $cat_id
return $this->tmp[$cat_id];
If you just need to retrieve the full tree out of the database, you can even simplify your query (get all records at once) and remove the recursive call in this function. You will need an extra check that will only set the $this->tmp[$catagory->id] when it does not exist and else it should merge the data with the existing data.

Categories