Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

add number and operators to array PHP

Tags:

php

I'm trying to add a row of numbers and operators to an array. How can i do it correctly?

What I wish is to separate each number group to one index and in the next index operator .

I need your help to show me where is the error in my code:

function toArray($s){

    $le = strlen($s);
    $j = 0;
    $ordered_numbers_operators = array();
    $operators = array('+','-','*','/','%','(',')');

    for ( $i=0;$i<$le;$i++ ){

        if ( in_array( $s[$i], $operators )  ) {
            $ordered_numbers_operators[$j] = $s[$i];
            $j++;

        } else {

            if ( $i+1 == $le ){
                $ordered_numbers_operators[$j] = $s[$i];

            } else {

                if ( $s[$i+1] !== in_array( $s[$i+1], $operators ))  {

                    if ( $s[$i+1] == in_array( $s[$i+1], $operators )){
                        echo "\$i = " . $i . "<br />" ;
                        $ordered_numbers_operators[$j]=$s[$i];
                        $j++;

                    } else {

                        $ordered_numbers_operators[$j] = $s[$i] . $s[$i+1];
                        $i++; $j++;
                    }

                }
            }
        }
    }

    return $ordered_numbers_operators;

    }

$string = '6+4*4+100+444*6*13*14';

$arr = toArray($string);

The expected result:

[0] => 6
[1] => +
[2] => 4
[3] => *
[4] => 4
[5] => +
[6] => 100
[7] => +  
[8] => 444  
[9] => *
[10] => 6
[11] => *
[12] => 13
[13] => *
[14] => 14    

The actual result:

[0] => 6
[1] => +
[2] => 4
[3] => *
[4] => 4
[5] => +
[6] => 1
[7] => 0
[8] => 0
[9] => +
[10] => 44
[11] => 4
[12] => *
[13] => 6
[14] => *
[15] => 13
[16] => *
[17] => 14
like image 862
Ginan Sayedali Avatar asked Jan 26 '18 19:01

Ginan Sayedali


People also ask

Does += work on arrays in PHP?

The + operator in PHP when applied to arrays does the job of array UNION. $arr += array $arr1; effectively finds the union of $arr and $arr1 and assigns the result to $arr .

What is Array_push in PHP?

Definition and Usage. The array_push() function inserts one or more elements to the end of an array. Tip: You can add one value, or as many as you like. Note: Even if your array has string keys, your added elements will always have numeric keys (See example below).

How do you sum an associative array in PHP?

PHP | array_sum() Function The array_sum() function returns the sum of all the values in an array(one dimensional and associative). It takes an array parameter and returns the sum of all the values in it. The only argument to the function is the array whose sum needs to be calculated.


3 Answers

Without regex, you can do this a lot more simply. See this example, to test and run:

<?php


function toArray($s){
    $operators = array('+','-','*','/','%','(',')');

    $finalArr = [];
    $curStr = '';
    foreach (str_split($s) as $char) {
        if (in_array($char, $operators)) {
            //Alright, we have an operator. Append the entire number
            $finalArr[] = $curStr;
            //And also the operator
            $finalArr[] = $char;
            //Reset the current string back to empty
            $curStr = '';
        } else {
            //Not an operator? Just keep appending the current number
            $curStr .= $char;
        }
    }

    //Add final leftover string
    if ($curStr !== '') { //Sanity check here (This shouldn't ever be empty, as you wouldn't end with an operator)
        $finalArr[] = $curStr;
    }

    //Return
    return $finalArr;
}

$string = '6+4*4+100+444*6*13*14';

$arr = toArray($string);

print_r($arr);
like image 109
ugh StackExchange Avatar answered Nov 13 '22 05:11

ugh StackExchange


You can do it with a regex and preg_split, a bit easier.

$parts = preg_split('~([+*/-])~', '6+4*4+100+444*6*13*14', -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
print_r($parts);

Demo: https://3v4l.org/oCrLG

Note the - as the last character in the character class is important. If you add more characters after that the - will create a range between the closest character on each side. Any characters you want to separate on can be added inside the []. If adding ] though be sure to escape it so the closure is correct. You can read more about character classes here, https://www.regular-expressions.info/charclass.html.

The character class also makes it so you don't need to escape special regex characters. You could also do it like this, which removes the character class.

$parts = preg_split('~(\+|\*|/|-)~', '6+4*4+100+444*6*13*14', -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
print_r($parts);

Demo: https://3v4l.org/Jha6P

Additionally whitespace can be made optional with \s* or \h* before and after the operators.

$parts = preg_split('~\h*([+*/-])\h*~', '6+4*4+100+444*6*13*14', -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
print_r($parts);
like image 34
chris85 Avatar answered Nov 13 '22 05:11

chris85


Another regex-free way is to use array_reduce.

You can use str_split to split the string into an array, and then use array_reduce to build your desired array (so that consecutive numbers are joined). Let's do that step by step. First, with a simple callback function in array_reduce, we get the same result as with str_split:

function toArray($string) {
    $chars = str_split($string);

    return array_reduce($chars, function($result, $current) {
        $result[] = $current;

        return $result;
    }, []);
}

$input = '6+4*4+100+444*6*13*14';
print_r(toArray($input));

/*
Array
(
    [0] => 6
    [1] => +
    [2] => 4
    [3] => *
    [4] => 4
    [5] => +
    [6] => 1
    [7] => 0
    [8] => 0
    [9] => +
    [10] => 4
    [11] => 4
    [12] => 4
    [13] => *
    [14] => 6
    [15] => *
    [16] => 1
    [17] => 3
    [18] => *
    [19] => 1
    [20] => 4
)
*/

Next step is to check the previous value and the current value when iterating over the characters in array_reduce. If they are both numbers, we want to join them:

function toArray($string) {
    $chars = str_split($string);

    return array_reduce($chars, function($result, $current) {
        $previous = $result[] = array_pop($result);

        if (is_numeric($previous) && is_numeric($current)) {
            $result[] = array_pop($result) . $current;
        } else {
            $result[] = $current;
        }

        return $result;
    }, []);
}

$input = '6+4*4+100+444*6*13*14';
print_r(toArray($input));

/*
Array
(
    [0] =>
    [1] => 6
    [2] => +
    [3] => 4
    [4] => *
    [5] => 4
    [6] => +
    [7] => 100
    [8] => +
    [9] => 444
    [10] => *
    [11] => 6
    [12] => *
    [13] => 13
    [14] => *
    [15] => 14
)
*/

Almost there! The array contains one extra element at index zero. (That's because we are getting the previous item with $previous = $result[] = array_pop($result);. Its value is null, because initially $result is an empty array, so array_pop returns null.) We can get rid of the extra element e.g. with array_slice:

function toArray($string) {
    $chars = str_split($string);

    $array = array_reduce($chars, function($result, $current) {
        $previous = $result[] = array_pop($result);

        if (is_numeric($previous) && is_numeric($current)) {
            $result[] = array_pop($result) . $current;
        } else {
            $result[] = $current;
        }

        return $result;
    }, []);

    return array_slice($array, 1);
}

$input = '6+4*4+100+444*6*13*14';
print_r(toArray($input));

/*
Array
(
    [0] => 6
    [1] => +
    [2] => 4
    [3] => *
    [4] => 4
    [5] => +
    [6] => 100
    [7] => +
    [8] => 444
    [9] => *
    [10] => 6
    [11] => *
    [12] => 13
    [13] => *
    [14] => 14
)
*/

Demo: https://3v4l.org/qZsvs

like image 41
Matias Kinnunen Avatar answered Nov 13 '22 07:11

Matias Kinnunen