I am using code igniter and I have an array which stores data sent from the form.
Sometimes user can type a text with a space, ex " John", or "James ", so I would like to use a trim() function to delete those whitespaces.
$data = array(
'name' => ' James',
'surname' => 'Doe ',
'street_name' => ' The Steet',
'number' => '45 flat 5/6 ',
'postcode' => ' 12-345 ',
'city' => ' New York ',
);
Instead of adding a trim to every single line in array I would prefer to add a function which will go key by key and use a trim function to every key in array. How to do that?
The array_map function applies a function to every element in an array. In this case, the function you want is trim.
$trimmedData = array_map('trim', $data);
Simplest vanilla code to understand the process
foreach($data as $key=>$val) {
$data[$key] = trim($val);
}
var_dump($data);
or use a function e.g. array_map()
$newarray = array_map("trim", $old_array);
A function?
function trim_whitespace_from_array( $input ){
foreach($input as $key=>$val) {
$input[$key] = trim($val);
}
return $input;
}
$data = array(
'name' => ' James',
'surname' => 'Doe ',
'street_name' => ' The Steet',
'number' => '45 flat 5/6 ',
'postcode' => ' 12-345 ',
'city' => ' New York ',
);
$trimmed = trim_whitespace_from_array($data);
Pretty much the same as what #donald123 said.
The function you want already exists. It's called array_map(). It allows one to call a custom function (that would be trim() in your case) on all the values from an array and produces an array from the values returned by that function; it preserves the keys.
$data = array_map('trim', $data);
Related
I have an array coming with the following structure:
$arr = [
traveler_name_1 => 'value',
hotel_name_1 => 'value',
hotel_in_date_1 => 'value',
traveler_name_2 => 'value',
hotel_name_2 => 'value',
hotel_in_date_2 => 'value',
traveler_name_n => 'value',
hotel_name_n => 'value',
hotel_in_date_n => 'value',
];
I want to check if the string without the index is valid and is allowed. For example:
$allowed_values = [
'traveler_name',
'hotel_name',
'hotel_in_date'
];
The easy way would be iterate over $arr as $key => $value pairs and then make an in_array() but for do that I need to remove first the last portion of the string, for example:
traveler_name_1 => remove the _1
hotel_name_1 => remove the _1
hotel_in_date_1 => remove the _1
So I can look for them on the $allowed_values array.
So the question is how do I remove that part from the string?
The values after the second _ are generated dynamically so they hasn't a constant length. The value before are constant.
If you have a better way to validate this then go ahead and let me know
One way (probably not the most efficient one) is to do this:
$s = "traveler_name_24872";
$arr = explode("_", $s);
array_pop($arr);
$s2 = implode("_", $arr); // traveler_name
depending on how you want to manipulate the data, this would return what you're looking for. You could then put the $index and $value in a new array or just manipulate the data from within that foreach loop.
This returns the full string minus the last two characters (via the -2). If you want to return all but the last 3 characters, you'd replace -2 with -3, etc.
foreach ($arr as $key => $value) {
$index = substr($key, 0, -2);
}
I have found the solution after some tries so here it's what I was looking for:
foreach ($arr as $key => $value) {
if (!in_array(substr(key($key), 0, strrpos(key($key), '_')), $allowed_values, true)) {
echo 'Not allowed';
break;
}
}
Thank you anyway
Let say I have the following string which I want to send as an email to a customer.
"Hello Mr/Mrs {{Name}}. You have subscribed for {{Service}} at {{Date}}."
And I have an array with the values that should be replaced
array(
'Name' => $customerName, //or string
'Service' => $serviceName, //or string
'Date' => '2015-06-06'
);
I can find all strings between {{..}} with this:
preg_match_all('/\{{(.*?)\}}/',$a,$match);
where $match is an array with values, But I need to replace every match with a corresponding value from an array with values
Note that the array with values contains a lot more values and the number of items in it or the keys sequence is not relevant to number of matches in string.
You can use preg_replace_callback and pass the array with the help of use to the callback function:
$s = "Hello Mr/Mrs {{Name}}. You have subscribed for {{Service}} at {{Date}} {{I_DONT_KNOW_IT}}.";
$arr = array(
'Name' => "customerName", //or string
'Service' => "serviceName", //or string
'Date' => '2015-06-06'
);
echo $res = preg_replace_callback('/{{(.*?)}}/', function($m) use ($arr) {
return isset($arr[$m[1]]) ? $arr[$m[1]] : $m[0]; // If the key is uknown, just use the match value
}, $s);
// => Hello Mr/Mrs customerName. You have subscribed for serviceName at 2015-06-06.
See IDEONE demo.
The $m[1] refers to what has been captured by the (.*?). I guess this pattern is sufficient for the current scenario (does not need unrolling as the strings it matches are relatively short).
You don't need to use a regex for that, you can do it with a simple replacement function if you change a little the array keys:
$corr = array(
'Name' => $customerName, //or string
'Service' => $serviceName, //or string
'Date' => '2015-06-06'
);
$new_keys = array_map(function($i) { return '{{' . $i . '}}';}, array_keys($corr));
$trans = array_combine($new_keys, $corr);
$result = strtr($yourstring, $trans);
Try
<?php
$str = "Hello Mr/Mrs {{Name}}. You have subscribed for {{Service}} at {{Date}}.";
$arr = array(
'Name' => 'some Cust', //or string
'Service' => 'Some Service', //or string
'Date' => '2015-06-06'
);
$replaceKeys = array_map(
function ($el) {
return "{{{$el}}}";
},
array_keys($arr)
);
$str = str_replace($replaceKeys, array_values($arr), $str);
echo $str;
I have an array like this:
$temp = array( '123' => array( '456' => array( '789' => '0' ) ),
'abc' => array( 'def' => array( 'ghi' => 'jkl' ) )
);
I have a string like this:
$address = '123_456_789';
Can I get value of $temp['123']['456']['789'] using above array $temp and string $address?
Is there any way to achieve this and is it good practice to use it?
This is a simple function that accepts an array and a string address where the keys are separated by any defined delimiter. With this approach, we can use a for-loop to iterate to the desired depth of the array, as shown below.
<?php
function delimitArray($array, $address, $delimiter="_") {
$address = explode($delimiter, $address);
$num_args = count($address);
$val = $array;
for ( $i = 0; $i < $num_args; $i++ ) {
// every iteration brings us closer to the truth
$val = $val[$address[$i]];
}
return $val;
}
$temp = array("123"=>array("456"=>array("789"=>"hello world")));
$address = "123_456_789";
echo delimitArray($temp,$address,"_");
?>
Hello if string $address = '123_456_789'; is your case then you can use explode function to split the string by using some delimeter and you can output your value
<?php
$temp = array('123' => array('456' => array('789' => '0')),
'abc' => array('def' => array('ghi' => 'jkl')),
);
$address = '123_456_789';
$addr = explode("_", $address);
echo $temp[$addr[0]][$addr[1]][$addr[2]];
Using this array library you can easily get element value by either converting your string to array of keys using explode:
Arr::get($temp, explode('_', $address))
or replacing _ with . to take advantage of dot notation access
Arr::get($temp, str_replace('_', '.', $address))
Another benefit of using this method is that you can set default fallback value to return if element with given keys does not exists in array.
I have an array called $Bond:
$Bond = array (
'Sean Connery' => 'Dr. No',
'George Lazenby' => 'On Her Majesty\'s Secret Service',
'Roger Moore' => 'Live and Let Die',
'Timothy Dalton' => 'The Living Daylights',
'Pierce Brosnan' => 'GoldenEye',
'Daniel Craig' => 'Casino Royal'
);
I need to extract ONLY the last names from the Keys & print them as uppercase.
How in the world would I go about that?
This would loop through each item and give you the last name.
foreach($box as $k=>$v){
$lastName = explode(' ',$k)[1];
echo strtoupper($lastName);
}
This could break if you had someone with a name like "Mary Jo" or "Bobby Jo" as a first name. In that case you may have to make some changes if this is going to occur.
Edit. I implemented the end function to ensure the last name.
foreach($box as $k=>$v){
$lastName = explode(' ',$k);
echo strtoupper(end($lastName));
}
You can follow several ways you can make an array of keys with array_keys() and then go through your array of keys with a for(), split the name with explode() and convert to upper the last name (end($info)) with strtoupper(). See the code:
<?php
$Bond = array (
'Sean Connery' => 'Dr. No',
'George Lazenby' => 'On Her Majesty\'s Secret Service',
'Roger Moore' => 'Live and Let Die',
'Timothy Dalton' => 'The Living Daylights',
'Pierce Brosnan' => 'GoldenEye',
'Daniel Craig' => 'Casino Royal'
);
$array_keys = array_keys($Bond);
for($i = 0; $i < count($array_keys); $i++) {
$info = explode(' ', $array_keys[$i]);
echo strtoupper(end($info)) . "<br>\n";
}
?>
Or you can go to through your array with the foreach() split the name with explode() and convert to upper the last name (end($info)) with strtoupper() something like this:
<?php
$Bond = array (
'Sean Connery' => 'Dr. No',
'George Lazenby' => 'On Her Majesty\'s Secret Service',
'Roger Moore' => 'Live and Let Die',
'Timothy Dalton' => 'The Living Daylights',
'Pierce Brosnan' => 'GoldenEye',
'Daniel Craig' => 'Casino Royal'
);
foreach($Bond as $key => $value) {
$info = explode(' ', $key);
echo strtoupper(end($info)) . "<br>\n";
}
?>
Output in both cases:
CONNERY
LAZENBY
MOORE
DALTON
BROSNAN
CRAIG
Since the actor names fall on the keys, use foreach, then you could just use strrchr + substr to get the last name:
foreach($Bond as $name => $movie) {
$last = strtoupper(substr(strrchr($name, ' '), 1));
echo $last, '<br/>';
}
Sample Output
This should work for you, nice and compact:
(Here I go through all array keys with array_keys(), where I then explode() each key by a space as delimiter. And then access the last element which I return in strtoupper() case)
<?php
$lastNamesUpper = array_map(function($v){
return strtoupper(explode(" ", $v)[substr_count($v, " ")]);
}, array_keys($Bond));
foreach($lastNamesUpper as $v)
echo "$v<br>";
?>
output:
CONNERY
LAZENBY
MOORE
DALTON
BROSNAN
CRAIG
So, having an array like the following:
$input = [
'first_name' => 'Alex',
'last_name' => 'UFO',
'email' => 'test#test.com',
'phone_number' => '124124',
// .....
'referral_first_name' => 'Jason',
'referral_last_name' => 'McNugget',
'referral_email' => 'jingleball#nuggets.com',
'referral_phone_number' => '1212415',
];
After processing the first part, until referral..., do you think of any better way to replace referral_first_name with first_name and so on, then the following? Maybe a more dynamic and automatic way.
$input['first_name'] = $input['referral_first_name'];
unset($input['referral_first_name']);
$input['last_name'] = $input['referral_last_name'];
unset($input['referral_last_name']);
$input['email'] = $input['referral_email'];
unset($input['referral_email']);
$input['phone_number'] = $input['referral_phone_number'];
unset($input['referral_phone_number']);
Guys, I forgot to mention, but I have already done it with foreach, but the problem will be when the array gets pretty large (and usually does, and not by one person using that function, but by many), and that would mean extra unnecessary processing time, since it has to iterate through the whole array, before reaching the referral_.. part.
you must create another array, this code should do it dynamically:
$newInput = array();
foreach($input as $key => $element){
$newKey = explode("_", $key, 2);
$newInput[$newKey[1]] = $element;
}
OUTPUT
hope this helps :-)
Recreating the array is the only way..
Grab all the keys from the original array and put it in a temp array
Use array_walk to modify that temp array to add the referral word to it
Now use array_combine using the above keys and values from the old array.
The code..
<?php
$input = [
'first_name' => 'Alex',
'last_name' => 'UFO',
'email' => 'test#test.com',
'phone_number' => '124124'];
$ak = array_keys($input);
array_walk($ak,function (&$v){ $v = 'referral_'.$v;});
$input=array_combine($ak,array_values($input));
print_r($input);
OUTPUT:
Array
(
[referral_first_name] => Alex
[referral_last_name] => UFO
[referral_email] => test#test.com
[referral_phone_number] => 124124
)
Since you are looking for performance , Use a typical foreach
$newarr = array();
foreach($input as $k=>$v ) {
$newarr["referral_".$k]=$v;
}
How about something like this:
$replace = array('first_name', 'last_name', 'email');
foreach($replace AS $key) {
$input[$key] = $input['referral_' . $key];
unset($input[$input['referral_' .$key]]);
}
try the below one...
$input = [
//'first_name' => 'Alex',
// 'last_name' => 'UFO',
// 'email' => 'test#test.com',
//'phone_number' => '124124',
// .....
'referral_first_name' => 'Jason',
'referral_last_name' => 'McNugget',
'referral_email' => 'jingleball#nuggets.com',
'referral_phone_number' => '1212415',
];
foreach ($input as $key=>$value){
$refereal_pos = strpos($key, 'referral_');
if($refereal_pos !== FALSE && $refereal_pos == 0){
$input[str_replace('referral_', '', $key)] = $value;
unset($input[$key]);
}
}
print_r($input);
You can use following;
function changeKeys($input) {
$keys = array_keys($input);
foreach($keys as $key) {
if (strpos($key, "referral_") !== false) {
$tempKey = explode("referral_", $key);
$input[$tempKey[1]] = $input[$key];
unset($input[$key]);
}
}
return $input;
}
changeKeys($input);
Here is a working demo: codepad
Note: Be sure that, your keys overwrited due to duplicate keys after "referral_" removal