This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Search and replace inside an associative array
I think this may have been asked before. But I just want a simple solution.
I have an array like this:
Array ( "name" => "Krish",
"age" => "27",
"COD" => ""
)
I want to replace "" with "0"
Its a multidimentional array. The return value should be array too.
Edit: I tried preg_replace and str_replace. For some reason, these did not work for me.
$array = array(
"name" => "Krish",
"age" => "27",
"COD" => ""
);
you may loop the array and repalce what you want
foreach($array as $key => $value)
{
if($value == "") $array[$key] = 0;
}
Note:
if you know what key is it you can do it like this
$array['cod'] = 0;
$entry = array("name" => "Krish",
"age" => "27",
"COD" => "");
$arr = array_filter($entry, 'valcheck');
print_r($entry); //ORIGINAL ARRAY
print_r($arr); //MODIFIED ARRAY
function valcheck($var)
{
if($var === "")
return 0;
else
return $var;
}
if your array is $array:
$array['COD'] = "0";
<?php
$arr=array(
"name" => "Krish",
"age" => "27",
"COD" => ""
);
print_r(array_map(function($i){return (''===$i)?0:$i;},$arr));
?>
Related
This question already has answers here:
How to access and manipulate multi-dimensional array by key names / path?
(10 answers)
Closed 6 years ago.
Let's assume that I have an array like following:
$settings = array(
"age" => "25",
"data" => array(
"name" => "John Dewey",
"zip_code" => "00000"
)
);
Here's my input:
$target_directory = "data.name"; // targets $settings["data"]["name"]
$new_value = "Micheal"; // I want to change
// $settings["data"]["name"] with this value
I want something similar to following:
$new_array = dont_know_what_to_do($target_directory, $new_value, $settings);
A print_r($new_array) should return following:
Array
(
[age] => 25
[data] => Array
(
[name] => Micheal,
"zip_code" => "00000"
)
)
The change should be totally dynamic, meaning that data.zip_code = "98985" should also change only the zip code value from 00000 to 98985, and so on...
Here is the dynamic set funciton, you can use it set any depth. Demo here for you question.
function set($settings, $target_directory, $new_value)
{
$array = explode('.', $target_directory);
$ref = &$settings;
while($v = current($array))
{
$ref = &$ref[$v];
next($array);
}
$ref = $new_value;
return $settings;
}
$settings = array(
"age" => "25",
"data" => array(
"name" => "John Dewey",
"zip_code" => "00000"
)
);
$new_value = "Micheal";
$settings["data"]["name"] = $new_value;
print_r($settings);
//In your main function
public function something() {
$settings = array(
"age" => "25",
"data" => array(
"name" => "John Dewey",
"zip_code" => "00000"
)
);
$target = 'data.name';
$input = 'Other Name'
$new_arr = dont_know_what_to_do($target_dir, $input);
print_r($new_arr);
}
//Create new function
public function dont_know_what_to_do($settings, $target, $input) {
$key = explode('.', $target)
return $settings['data'][$key[1]] = $input;
}
To be short, I have two simple arrays and I want to verify if certain keys from the second array have empty values and replace them with their correspondent values from the first array.
Example:
$a1 = [ 1 => 'one', 2 => 'two', 3 => 'three',5=>'cinco', 6=>'six'];
$a2 = [ 2 => 'two', 5=>'five', 6=>'' ];
Result:
Array
(
[2] => two
[5] => five
[6] => six
)
The following code works already for this.
$keys = array_keys($a1);
foreach ($keys as $k)
{
if ((isset($a2[$k])) && (($a2[$k]) == '')) {
$a2[$k] = $a1[$k];
}
}
print_r($a2);
But what if we want to apply this for two 2D arrays? What will be the proper approach in that case? Let's say these two 2D arrays will be:
$superheroes_complete = array(
"spiderman" => array(
"name" => "Peter Parker",
"email" => "peterparker#mail.com",
),
"superman" => array(
"name" => "Clark Kent",
"email" => "clarkkent#mail.com",
),
"ironman" => array(
"name" => "Harry Potter",
"email" => "harrypotter#mail.com",
)
);
$superheroes_empty = array(
"spiderman" => array(
"name" => "Peter Parker",
"email" => "",
),
"superman" => array(
"name" => "Clark Kent",
"email" => "something",
),
"ironman" => array(
"name" => "Harry Potter",
"email" => "another one",
)
);
Expectation:
$superheroes = array(
"spider-man" => array(
"name" => "Peter Parker",
"email" => "peterparker#mail.com",
),
"super-man" => array(
"name" => "Clark Kent",
"email" => "something",
),
"iron-man" => array(
"name" => "Harry Potter",
"email" => "another one",
)
);
Much appreciation and thank you in advance!
You've added another level to your data, so you can just add another level to your checking as well with a second foreach loop:
foreach ($superheroes_complete as $hero => $info) {
foreach ($info as $key => $value) {
if (empty($superheroes_empty[$hero][$key])) {
$superheroes_empty[$hero][$key] = $value;
}
}
}
First note that your 1D case can be simplified:
foreach ($a2 as $k => $v) {
if (!isset($v)) {
$a2[$k] = $a1[$k];
}
}
Then for the 2D case, assuming the 1st level keys are always the same (or it becomes a quite different question!):
foreach ($superheroes_complete as $main_k => $main_v) {
foreach ($main_v as $k => $v) {
if (!isset($v)) {
$superheroes_empty[$main_k][$k] = $superheroes_complete[$main_k][$k];
}
}
If you only need to take care of the "email" field you can do this :
<?php
$keys = array_keys($superheroes_complete);
foreach ($keys as $k)
{
if ((isset($superheroes_empty[$k]["email"])) &&
(($superheroes_empty[$k]["email"]) == '')) {
$superheroes_empty[$k]["email"] = $superheroes_complete[$k]["email"];
}
}
var_dump($superheroes_empty);
?>
For the generic case where the depth of nesting is unlimited, you could use this recursive function:
function fillEmpty(&$filled, &$empty) { // arguments are by reference
if ($empty === "") {
$empty = $filled;
return;
}
if (!is_array($filled) || !is_array($empty)) return;
foreach ($filled as $key => $value) {
if (isset($empty[$key])) fillEmpty($value, $empty[$key]);
}
}
Example call:
fillEmpty($superheroes_complete, $superheroes_empty);
This modifies the second argument, filling the empty values.
See it run on eval.in
It might be your lucky day, php has some built in functions to compare arrays values and keys. Use array_diff() which can compare two or more arrays and return the difference. You could also use array_intersect() which does the opposite.
If you want to only compare the keys, use array_diff_key()which returns only the key difference or array_intersect_key() which returns the matched keys.
You could also consider a recursive solution. This could work on both the 1D and 2D arrays, or even an array of N dimensions.
I'm aware that recursion should be used with care, as it can be quite resource intensive. This is however a more versatile solution, and keeps the code cleaner with less nested control structures and early returns, which I find better readable. I'll use the native array_walk method because I was taught that it should perform better then a php loop.
So this is what my code would look like:
function array_complement_recursive(&$partial, $complete) {
array_walk($partial, function(&$value, $key) use ($complete) {
// (for safety) complete does not contain matching key: done
if (! array_key_exists($key, $complete)) {
return;
}
// value is array: call recursive
if (is_array($value)) {
array_complement_recursive($value, $complete[$key]);
return;
}
// value is not 'empty': done
// note that null, 0, false will also not match, you may want to make
// this check more specific to match only the empty string
if ($value) {
return;
}
$value = $complete[$key];
});
}
I've set up a little demo so you can see that it works on both your examples. And as I said, it should even work for arrays with more dimensions, or a more irregular structure.
http://phpfiddle.org/main/code/49iz-vrwg
I've added some comments to explain, but feel free to ask if anything is unclear.
I have a array like this:
$arr = array(
"0" => "Jack",
"1" => "Peter",
"2" => "ali"
);
Now I want to add My name is: to the first of all those values...! How can I do that?
Note: I can do that using a loop, and fetch all values, and combine them using . and push them into array again. But I want to know is there any function for doing that? Or any better solution?
So I want this output:
$newarr = array(
"0" => "My name is: Jack",
"1" => "My name is: Peter",
"2" => "My name is: ali"
);
Use array_walk as below :
<?php
$arr = array (
"0" => "Jack",
"2" => "Peter",
"3" => "ali"
);
array_walk($arr, function(&$item) {
$item = 'My Name is : '.$item;
});
print_r($arr);
?>
or you can use array_map as below
<?php
$arr = array (
"0" => "Jack",
"2" => "Peter",
"3" => "ali"
);
$arr = array_map(function($val) {
return "My name is : ".$val;
} , $arr);
print_r($arr);
?>
Use array_walk. It Applies a user supplied function to every member of an array. In your case, we are going to concatenate your string. See the example below.
<?php
$arr = array(
"0" => "Jack",
"2" => "Peter",
"3" => "ali"
);
array_walk($arr, function(&$name) {
$name = 'My Name is : ' . $name;
});
echo '<pre>';
print_r($arr);
echo '</pre>';
?>
you can use array_map function, see code
$arr = array (
"0" => "Jack",
"2" => "Peter",
"3" => "ali"
);
function changeName($name)
{
return('My name is: '.$name);
}
$b = array_map("changeName", $arr);
print_r($b);
A better solution is to only output the "My name is:" when needed. You may use array_map or a foreach loop.
If you keep the array with only names you can reuse it more easily in the future.
Consider the following cases:
sorting the names
providing a different string for the same array later in the code
using the names without the string later in the code
Also, you don't have to explicitly set the keys in this case, you could use notation like this:
$names = [ "Jim", "Dave"];
Use a for loop which uses the original array elements:
$arr = array (
"0" => "Jack",
"1" => "Peter",
"2" => "ali"
);
for ($i=0;$i<count($arr);$i++)
$arr[$i] = "My name is: " . $arr[$i];
print_r($arr);
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Pattern Match on a Array Key
I need to get all the elements in an array with a specific key pattern. For example in this array:
$items = array(
"a" => "1",
"b" => "2",
"special_1" => "3",
"c" => "4",
"special_2" => "5",
"special_3" => "6",
"d" => "7"
);
I would need all elements with a key containing the string special_. These should define a new array:
$special_items = array(
"special_1" => "3",
"special_2" => "5",
"special_3" => "6",
);
Is there a smart method besides a while loop?
How about this?
$special_items = array();
foreach($items as $key => $val) {
if(substr($key, 0, 8) == 'special_')
$special_items[$key] = $val;
}
First you need to get an array containing the keys. array_keys
Then, you need to filter the keys to find the ones you want. array_filter
Use this callback:
function($a) {return substr($a,0,8) == "special_";}
Then flip the array so that the keys are keys again instead of values. array_flip
Finally, intersect those keys with the original array. array_intersect_key
Result:
$special_items = array_intersect_key($items,array_flip(array_filter(array_keys($items),function($a) {return substr($a,0,8) == "special_";})));
You can use FilterIterator
$iterator = new SpecialFilter($items, 'special');
var_dump(iterator_to_array($iterator));
Output
array
'special_1' => string '3' (length=1)
'special_2' => string '5' (length=1)
'special_3' => string '6' (length=1)
Class Used
class SpecialFilter extends FilterIterator {
private $f;
public function __construct(array $items, $filter) {
$object = new ArrayObject( $items );
$this->f = $filter;
parent::__construct( $object->getIterator() );
}
public function accept() {
return 0 === strpos( $this->getInnerIterator()->key(), $this->f );
}
}
$special_items = array_intersect_key(array_flip(preg_grep('/^special_\d+/', array_keys($items))), $items);
Please don't actually use that. Just use a foreach loop with strpos + an if statement like all normal people would.
how about
$keys = preg_grep( "/special_/i", array_keys( $items ) );
$new_array = array();
foreach( $keys as $k )
{
$new_array[ $k ] = $items[ $k ];
}
This question already has answers here:
Is there a function to extract a 'column' from an array in PHP?
(15 answers)
Closed 5 months ago.
This is more a request for a quick piece of advice as, I find it very hard to believe there isn't a native function for the task at hand. Consider the following:
array =>
(0) => array("id" => "1", "groupname" => "fudge", "etc" => "lorem ipsum"),
(1) => array("id" => "2", "groupname" => "toffee", "etc" => "lorem ipsum"),
(2) => array("id" => "3", "groupname" => "caramel", "etc" => "lorem ipsum")
)
What I am looking to get is a new array which uses only "groupname" so would equal:
array =>
(0) => "fudge",
(1) => "toffee",
(2) => "caramel"
)
I know this is very simple to achieve recursively going through the original array, but I was wondering if there is a much simpler way to achieve the end result. I've looked around the internet and on the PHP manual and can't find anything
Thank you kindly for reading this question
Simon
There is a native array_column() function exactly for this (since PHP 5.5):
$column = array_column($arr, 'groupname');
If you are using PHP 5.3, you can use array_map [docs] like this:
$newArray = array_map(function($value) {
return $value['groupname'];
}, $array);
Otherwise create a normal function an pass its name (see the documentation).
Another solution is to just iterate over the array:
$newArray = array();
foreach($array as $value) {
$newArray[] = $value['groupname'];
}
You definitely don't have to use recursion.
Use array_map:
<?php
$a = array(
array("id" => "1", "groupname" => "fudge", "etc" => "lorem ipsum"),
array("id" => "2", "groupname" => "toffee", "etc" => "lorem ipsum"),
array("id" => "3", "groupname" => "caramel", "etc" => "lorem ipsum")
);
function get_groupname( $arr )
{
return $arr['groupname'];
}
$b = array_map( 'get_groupname', $a );
var_dump( $a );
var_dump( $b );
http://codepad.org/7kNi8nNm
Values by all array keys:
$array = [
["id"=>"1","user"=>"Ivan"],
["id"=>"2","user"=>"Ivan"],
["id"=>"3","user"=>"Elena"]
];
$res = [];
$array_separate = function($value, $key) use (&$res){
foreach($value AS $k=>$v) {
$res[$k][] = $v;
}
};
array_walk($array, $array_separate);
print_r($res);
result:
Array
(
[id] => Array
(
[0] => 1
[1] => 2
[2] => 3
)
[user] => Array
(
[0] => Ivan
[1] => Ivan
[2] => Elena
)
)
http://sandbox.onlinephpfunctions.com/code/3a8f443283836468d8dc232ae8cc8d11827a5355
As far as I know there isn't a simple function in PHP that could handle this for you, the array structure is user-defined, you would have to loop through the array. The easiest way I can think of would be something like this:
for($i = 0;$i < count($main_array);$i++){
$groupname_array[] = $main_array[$i]["groupname"];
}
function array_get_keys(&$array, $key) {
foreach($array as &$value) $value = $value[$key];
}
array_get_keys($array, 'groupname');
or
function array_get_keys(&$array, $key) {
$result = Array();
foreach($array as &$value) $result[] = $value[$key];
return $result;
}
$new_array = array_get_keys($array, 'groupname');