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
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 .
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).
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.
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);
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);
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With