Viewed   117 times

I need to design a function to return negative numbers unchanged but should add a + sign at the start of the number if its already no present.


Input     Output
+1         +1
1          +1
-1         -1

It will get only numeric input.

function formatNum($num)
# something here..perhaps a regex?

This function is going to be called several times in echo/print so the quicker the better.


Thank you all for the answers. I must tell the sprintf based solution is really fast.



You can use regex as:

function formatNum($num){
    return preg_replace('/^(d+)$/',"+$1",$num);

But I would suggest not using regex for such a trivial thing. Its better to make use of sprintf here as:

function formatNum($num){
    return sprintf("%+d",$num);

From PHP Manual for sprintf:

An optional sign specifier that forces a sign (- or +) to be used on a number. By default, only the - sign is used on a number if it's negative. This specifier forces positive numbers to have the + sign attached as well, and was added in PHP 4.3.0.

Wednesday, November 9, 2022

You can break each data by - and build the array in as much as needed. Notice the use of & in the code as using reference to result array.


$str = "15-02-01-0000,15-02-02-0000,15-02-03-0000,15-02-04-0000,15-02-05-0000,15-02-10-0000,15-02-10-9100,15-02-10-9101,15-15-81-0000,15-15-81-0024";
$arr = explode(",", $str);
$res = [];
foreach($arr as $e) { // for each line in your data
    $a = explode("-", $e); //break to prefix
    $current = &$res; 
    while(count($a) > 1) { // create the array to that specific place if needed
        $key = array_shift($a); // take the first key
        if (!isset($current[$key])) // if the path not exist yet create empty array 
            $current[$key] = array();
        $current = &$current[$key];
    $current[] = $e; // found the right path so add the element

The full result will be in $res.

Monday, October 10, 2022

I agree with the comments about not using a numbering scheme like this if the numbers are going to be used for anything other than a simple ordered display of items with numbers. If the numbers are actually going to be tied to something, then this is a really bad idea!

Use a variable, and increment it in the SELECT statement:

    (@row:=@row+1) AS row
FROM table,
(SELECT @row:=0) AS row_count;


CREATE TABLE `table1` (
    `id` int(11) NOT NULL auto_increment,
    PRIMARY KEY  (`id`)

INSERT INTO table1 VALUES (24), (87), (112);

    (@row:=@row+1) AS row
FROM table1,
(SELECT @row:=0) AS row_count;

| id  | row  |
|  24 |    1 |
|  87 |    2 |
| 112 |    3 |

How it works

@row is a user defined variable. It is necessary to set it to zero before the main SELECT statement runs. This can be done like this:

SELECT @row:=0;

or like this:

SET @row:=0

But it is handy to tie the two statements together. This can be done by creating a derived table, which is what happens here:

FROM table,
(SELECT @row:=0) AS row_count;

The the second SELECT actually gets run first. Once that's done, it's just a case of incrementing the value of @row for every row retrieved:


The @row value is incremented every time a row is retrieved. It will always generate a sequential list of numbers, no matter what order the rows are accessed. So it's handy for some things, and dangerous for other things...

Saturday, August 27, 2022

Have you tried a testing engine like regexpal (there are others available also) I frequently use this to test various strings against expressions to make sure they are behaving as expected.

My understanding is that in this case the : is not acting alone it is acting in conjunction with the ?

The ? in this circumstance does not mean Preceding zero or one times it is a modifier meaning give this group a new meaning which in conjunction with the modifier : turn off capture means you want this to be a non capturing group expression.

The effect that this has is that when placing part of an expression inside () it by default causes capture but ?: switches this off.

Thus (?:[-s]?d) becomes a non capturing group expression.

Note captured groups are used with back references and most regex engines support up to 9 back references.

So removing capture speeds up the matching process and allows you to elect not to refer back to that group saving one of your 9 references for a group that you really do want to refer back to.

Monday, August 1, 2022

New answer

Re your revised question: foreach actually works with properties as well as with many-valued items (arrays), details here. So for instance, with the JSON string in your question:

$data = json_decode($json);
foreach ($data as $name => $value) {
    // This will loop three times:
    //     $name = inbox
    //     $name = sent
    //     $name = draft
    // ...with $value as the value of that property

Within your main loop over the properties, you can use an inner loop to go over the array entries each property points to. So for instance, if you know that each of the top-level properties has an array value, and that each array entry has a "firstName" property, this code:

$data = json_decode($json);
foreach ($data as $name => $value) {
    echo $name . ':'
    foreach ($value as $entry) {
        echo '  ' . $entry->firstName;

...will show:


Old answer(s)

Begin edit Re your comment:

Now I would like to know how to decode JSON string with several objects!

The example you posted does have several objects, they're just all contained within one wrapper object. This is a requirement of JSON; you cannot (for example) do this:

{"name": "I'm the first object"},
{"name": "I'm the second object"}

That JSON is not valid. There has to be a single top-level object. It might just contain an array:

{"objects": [
    {"name": "I'm the first object"},
    {"name": "I'm the second object"}

...or of course you can give the individual objects names:

    "obj0": {"name": "I'm the first object"},
    "obj1": {"name": "I'm the second object"}

End edit

Your example is one object containing three properties, the value of each of which is an array of objects. In fact, it's not much different from the example in the question you linked (which also has an object with properties that have array values).


$data = json_decode($json);
foreach ($data->programmers as $programmer) {
    // ...use $programmer for something...
foreach ($data->authors as $author) {
    // ...use $author for something...
foreach ($data->musicians as $musician) {
    // ...use $musician for something...
Thursday, September 8, 2022
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :