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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.