0

How can I transform

Array1
(
    [0] => Some Text
    [1] => Some Other Text (+£14.20)
    [2] => Text Text (+£26.88)
    [3] => Another One (+£68.04)
)

Into associative array like the one below:

Array2
(
    [Some Text] => 0 //0 since there is no (+£val) part
    [Some Other Text] => 14.20
    [Text Text] => Text Text 26.88
    [Another One] => 68.04
)
1
  • 2
    What do you have so far, and how does it not work? Commented Sep 5, 2011 at 5:05

3 Answers 3

2
$newArray = array();
foreach( $oldArray as $str ) {
    if( preg_match( '/^(.+)\s\(\+£([\d\.]+)\)$/', $str, $matches ) ) {
        $newArray[ $matches[1] ] = (double)$matches[2];
    } else {
        $newArray[ $str ] = 0;
    }
}
Sign up to request clarification or add additional context in comments.

Comments

1

Something like this should work:

$a2 = array();
foreach ($Array1 as $a1) {
    if (strpos($a1, '(') > 0) {
      $text = substr($a1, 0, strpos($a1, '('));
      $value = substr($a1, strpos($a1, '(')+3, strpos($a1, ')')-1);
    } else {
      $text = $a1;
      $value = 0;
    }
    $a2[$text] = $value;    
}
print_r($a2);

Output: (Demo)

Array
(
    [Some Text] => 0
    [Some Other Text ] => £14.20)
    [Text Text ] => £26.88)
    [Another One ] => £68.04)
)

EDIT:

You can do this using explode method as well:

$a2 = array();
foreach ($Array1 as $a1) {
    $a1explode = explode("(", $a1, 2);
    $text = $a1explode[0];
    if ($a1explode[1]) {
       $value = substr($a1explode[1],3);
    } else {
       $value = 0;
    }
    $a2[$text] = $value;    
}
print_r($a2);

Output: (Demo)

Warning: Undefined array key 1
Array
(
    [Some Text] => 0
    [Some Other Text ] => 14.20)
    [Text Text ] => 26.88)
    [Another One ] => 68.04)
)

3 Comments

regular expressions and explode are other options depending on the consistency of the data.
Thanks Its close but its not working in situations where "some text (text text) (+£14.20)"
"(" to "(+" now there is only one round bracket at the end " [text text ] => 7.18) "
0

sscanf() has its merits for this task. It will accommodate strings that only contain the item text and no price. It will cast the price directly as a float type value. Unfortunately, it is not equipped to trim the trailing space from the item text (before the opening parenthesis). Also, to prevent a subsequent value without a price from being assigned the price from the previous item, the price variable will need to be unset.

Code: (Demo)

$result = [];
foreach ($array as $v) {
    sscanf($v, '%[^(](+£%f)', $item, $price);
    $result[rtrim($item)] = $price ?? 0;
    unset($price);
}
var_export($result);

Or unconditionally append (+£0) to each input string to ensure a price. (Demo)

$result = [];
foreach ($array as $v) {
    sscanf($v . ' (+£0)', '%[^(](+£%f)', $item, $price);
    $result[rtrim($item)] = $price;
}
var_export($result);

preg_split() can be used as well without a terribly cumbersome regex pattern. (Demo)

$result = [];
foreach ($array as $v) {
    $a = preg_split('/ \(\+£([^)]+)\)/', $v, 2, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
    $result[$a[0]] = (float) ($a[1] ?? 0);
}
var_export($result);

Here's a deviation from @nobody's preg_match() snippet: (Demo)

$result = [];
foreach ($array as $v) {
    $result += preg_match("/(.+) \(\+£([^)]+)\)/", $v, $m) ? [$m[1] => (float) $m[2]] : [$v => 0];
}
var_export($result);

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.