I have this simple function which I pass in an array of strings:
function myfunction( $arg = array() )
{
// do stuff to $arg...
// return a $string;
}
Simple so far, but I need some of the strings in the $arg
array to be formatted, while some remain unformatted. I can't figure out how to do it?
Say I r开发者_JAVA百科un this $arg
through myfunction()
:
echo myfunction( array( 'format me!', 'do not format me!' ) );
My tiny little brain can't figure out how to tell myfunction()
that the first value in $arg
array needs to have formatting, and it should not format the second value.
I thought about an associative array, but I think that could be the wrong approach because of having identical indexes.
echo myfunction( array( 'format' => 'hi', 'format' => 'bye', 'noformat' => 'foo');
Just looking for a "nudge" in the right direction.
EDIT 1:
Forgot to mention, I can only have one $arg
array because I need the keys to be in a specific order.
EDIT 2:
The $arg
array can have as many keys as the user wants.
You can do:
function myfunction(array $format, array $noformat) {
...
}
or
function myfunction(array $strings) {
foreach ($strings['format'] as $format) {
// do stuff
}
foreach ($strings['noformat'] as $noformat) {
// do stuff
}
}
with:
myfunction(array(
'format' => array('one', 'two', 'three'),
'noformat' => array('four', 'five', 'six'),
));
If (and only if) the strings are unique you can put them in the key instead of the value:
$strings = array(
'one' => true,
'two' => false,
'three' => false,
'four' => true,
);
myfunction($strings);
with:
function myfunction(array $strings) {
foreach ($strings as $k => $v) {
if ($v) {
// format string
}
}
}
But since you can't have duplicate keys this method falls down if you have repeated strings.
Instead of having myfunction()
take an array as an argument, why not just have it take a single element as the argument. Then you can use array_map
to process each element of the array.
Sort of like this:
function myfunction($element) {
if( do-formatting) {
//do your formatting stuff
$element = formatted-stuff
}
return $element
}
$arr = array("format me", "don't format me");
//This calls myfunction on each element of the array
//A new array is returned where each element has been replaced
//by the return value from myfunction.
$arr = array_map('myfunction', $arr);
Here is how I would to it. The implementation of __tostring is not mandatory but is syntax sugar inside the myFunction.
<?php
class MyString{
private $_value;
public $to_format;
public function __construct($str, $to_format = true){
$this->_value = $str;
$this->to_format = $to_format;
}
public function __tostring(){
return $this->_value;
}
}
$args = array( new MyString('format me'), new MyString('Not me!', false) );
This is oddly similar to how table rows are formatted (with a different formatting function for each row). I would provide the data as a single array, then provide formatting information as a second array based on keys. For instance:
function rowFormatter(Array $data, Array $format=array()) {
ob_start();
foreach ($data as $key => $value) {
if (isset($format[$key]))
echo call_user_func($format[$key],$value);
else
echo $value;
}
return ob_get_clean();
}
function makeBold($x) { return '<b>'.$x.'</b>'; }
rowFormatter(array( "Hello", "Mister" ), array( 0 => 'makeBold' ));
I don't know what these strings you are formatting actually represent, so I used generic naming on these classes:
class LineItem
{
var $value;
function __construct($val)
{
$this->value = $val;
}
function __toString()
{
return $this->value;
}
function getFormatted( $formatter )
{
return $this->value;
}
}
class FormattedLineItem extends LineItem
{
function getFormatted( $formatter )
{
return $formatter( $this->value );
}
}
function myfunction( $arr=array() )
{
$fnFormat = function($str) {
return ucwords($str);
};
foreach($arr as $obj)
{
$str = $obj->getFormatted($fnFormat);
echo "$str\n";
}
}
$arr = array(
new FormattedLineItem('format me!'),
new LineItem('do not format me!')
);
myfunction($arr);
The idea is to use separate classes to distinguish between strings.
精彩评论