This question already has answers here:
PHP - split String in Key/Value pairs
(5 answers)
Convert backslash-delimited string into an associative array
(4 answers)
Closed 12 months ago.
i have a string like
$str = "1-a,2-b,3-c";
i want to convert it into a single array like this
$array = [
1 => "a",
2 => "b",
3 => "c"
];
what i do is
$str = "1-a,2-b,3-c";
$array = [];
$strex = explode(",", $str);
foreach ($strex as $str2) {
$alphanumeric = explode("-", $str2);
$array[$alphanumeric[0]] = $alphanumeric[1];
}
can i do this in a better way?
You can use preg_match_all for this:
<?php
$str = "1-a,2-b,3-c";
preg_match_all('/[0-9]/', $str, $keys);
preg_match_all('/[a-zA-Z]/', $str, $values);
$new = array_combine($keys[0], $values[0]);
echo '<pre>'. print_r($new, 1) .'</pre>';
here we take your string, explode() it and then preg_match_all the $value using patterns:
/[0-9]/ -> numeric value
/[a-zA-Z]/ -> letter
then use array_combine to get it into one array
Thanks to u_mulder, can shorten this further:
<?php
$str = "1-a,2-b,3-c";
preg_match_all('/(\d+)\-([a-z]+)/', $str, $matches);
$new = array_combine($matches[1], $matches[2]);
echo '<pre>'. print_r($new, 1) .'</pre>';
just a little benchmark:
5000 iterations
Debian stretch, php 7.3
parsed string: "1-a,2-b,3-c,4-d,5-e,6-f,7-g,8-h,9-i"
[edit] Updated with the last 2 proposals [/edit]
You can use preg_split with array_filter and array_combine,
function odd($var)
{
// returns whether the input integer is odd
return $var & 1;
}
function even($var)
{
// returns whether the input integer is even
return !($var & 1);
}
$str = "1-a,2-b,3-c";
$temp = preg_split("/(-|,)/", $str); // spliting with - and , as said multiple delim
$result =array_combine(array_filter($temp, "even", ARRAY_FILTER_USE_KEY),
array_filter($temp, "odd",ARRAY_FILTER_USE_KEY));
print_r($result);
array_filter — Filters elements of an array using a callback function
Note:- ARRAY_FILTER_USE_KEY - pass key as the only argument to callback instead of the value
array_combine — Creates an array by using one array for keys and another for its values
Demo
Output:-
Array
(
[1] => a
[2] => b
[3] => c
)
One way to do with array_map(),
<?php
$my_string = '1-a,2-b,3-c';
$my_array = array_map(function($val) {list($key,$value) = explode('-', $val); return [$key=>$value];}, explode(',', $my_string));
foreach(new RecursiveIteratorIterator(new RecursiveArrayIterator($my_array)) as $k=>$v){
$result[$k]=$v;
}
print_r($result);
?>
WORKING DEMO: https://3v4l.org/aYmOH
Tokens all the way down...
<?php
$str = '1-a,2-b,3-c';
$token = '-,';
if($n = strtok($str, $token))
$array[$n] = strtok($token);
while($n = strtok($token))
$array[$n] = strtok($token);
var_export($array);
Output:
array (
1 => 'a',
2 => 'b',
3 => 'c',
)
Or perhaps more terse without the first if...:
$array = [];
while($n = $array ? strtok($token) : strtok($str, $token))
$array[$n] = strtok($token);
Not a better way but one more example:
$str = "1-a,2-b,3-c";
$arr1 = explode(",", preg_replace("/\-([a-zA-Z]+)/", "", $str));
$arr2 = explode(",", preg_replace("/([0-9]+)\-/", "", $str));
print_r(array_combine($arr1, $arr2));
Mandatory one-liner (your mileage may vary):
<?php
parse_str(str_replace([',', '-'], ['&', '='], '1-a,2-b,3-c'), $output);
var_export($output);
Output:
array (
1 => 'a',
2 => 'b',
3 => 'c',
)
You can do one split on both the , and -, and then iterate through picking off every other pair ($k&1 is a check for an odd index):
<?php
$str = '1-a,2-b,3-c';
foreach(preg_split('/[,-]/', $str) as $k=>$v) {
$k&1 && $output[$last] = $v;
$last = $v;
}
var_export($output);
Output:
array (
1 => 'a',
2 => 'b',
3 => 'c',
)
The preg_split array looks like this:
array (
0 => '1',
1 => 'a',
2 => '2',
3 => 'b',
4 => '3',
5 => 'c',
)
This one explodes the string as the OP has on the comma, forming the pairs: (1-a) and (2-b) etc. and then explodes those pairs. Finally array_column is used to create the associated array:
<?php
$str = '1-a,2-b,3-c';
$output =
array_column(
array_map(
function($str) { return explode('-', $str); },
explode(',', $str)
),
1,
0
);
var_export($output);
Output:
array (
1 => 'a',
2 => 'b',
3 => 'c',
)
Related
Below is an array of strings and numbers. How could the string and number values be split into separate arrays (with strings in one array and numbers in another array)?
array('a','b','c',1,2,3,4,5,'t','x','w')
You could also do this in one line using array_filter()
$numbers = array_filter($arr,function($e){return is_numeric($e);});
$alphas = array_filter($arr,function($e){return !is_numeric($e);});
print_r($numbers);
print_r($alphas);
Loop through them, check if is_numeric and add to appropriate array:
$original = array('a','b','c',1,2,3,4,5,'t','x','w');
$letters = array();
$numbers = array();
foreach($original as $element){
if(is_numeric($element)){
$numbers[] = $element;
}else{
$letters[] = $element;
}
}
https://3v4l.org/CAvVp
Using a foreach() like in #jnko's answer will be most performant because it only iterates over the array one time.
However, if you are not concerned with micro-optimization and prefer to write concise or functional-style code, then I recommend using array_filter() with is_numeric() calls, then making key comparisons between the first result and the original array.
Code: (Demo)
$array = ['a','b',0,'c',1,2,'ee',3,4,5,'t','x','w'];
$numbers = array_filter($array, 'is_numeric');
var_export($numbers);
var_export(array_diff_key($array, $numbers));
Output:
array (
2 => 0,
4 => 1,
5 => 2,
7 => 3,
8 => 4,
9 => 5,
)
array (
0 => 'a',
1 => 'b',
3 => 'c',
6 => 'ee',
10 => 't',
11 => 'x',
12 => 'w',
)
$data = array('a','b','c',1,2,3,4,5,'t','x','w');
$integerArray = array();
$stringArray = array();
$undefinedArray = array();
foreach($data as $temp)
{
if(gettype($temp) == "integer")
{
array_push($integerArray,$temp);
}elseif(gettype($temp) == "string"){
array_push($stringArray,$temp);
}else{
array_push($undefinedArray,$temp);
}
}
I have two integers for example "12345" and "98754", they have a count of 2 matching numbers
namely 4 and 5, the order doesnt matter.
Now: How do I check something like that in PHP?
You can split the inputs to arrays and use array_intersect to find matching numbers.
$a = 12345;
$b = 98754;
//Create arrays of the numbers
$a = str_split($a);
$b = str_split($b);
// Find matching numbers
$matching = array_intersect($a, $b);
Var_dump($matching);
// Output: 4,5
Echo count($matching);
// Output: 2
https://3v4l.org/8tS3q
Convert the numbers in to strings
create a loop from 0-9 to check for the appearance of a number in both strings using strstr() or similar
store the number in an array if it appears in both
Edit:
Code-centric solution:
$a = 1231534;
$b = 89058430;
$matches = compare( $a, $b );
print count($matches);
function compare ( $a, $b ) {
$str_a = (string) $a;
$str_b = (string) $b;
$matches = [];
for($i=0;$i<=9;$i++) {
if (strstr($str_a, (string)$i) && strstr($str_b,(string)$i)) $matches[] = $i;
}
return $matches;
}
Added an example here that counts digits that occur in both numbers.
If multiple digits occur in both, these are included:
<?php
function digits_in_both($x, $y)
{
$in_both = [];
$split_y = str_split($y);
foreach(str_split($x) as $n) {
$key = array_search($n, $split_y);
if($key !== false) {
$in_both[] = $n;
unset($split_y[$key]);
}
}
return $in_both;
}
$in_both = digits_in_both(123445, 4456);
var_export($in_both);
var_dump(count($in_both));
Output:
array (
0 => '4',
1 => '4',
2 => '5',
)int(3)
Contrary to what you expect with array_intersect, order matters as demonstrated here:
var_export(array_intersect(str_split('024688'), str_split('248')));
var_export(array_intersect(str_split('248'), str_split('024688')));
Output:
array (
1 => '2',
2 => '4',
4 => '8',
5 => '8',
)array (
0 => '2',
1 => '4',
2 => '8',
)
This question already has answers here:
Converting CSV to PHP Array - issue with end line (CR LF)
(2 answers)
Closed 5 years ago.
$str = "a,b,c";
Can the above string be converted to an array of comma separated key value pair in php., so that the ouput is like below?
array('a' => 'a', 'b' => 'b', 'c' => 'c')
You can use explode() to achieve this.
$str = "a,b,c";
$array = array();
foreach( explode( ',', $str ) as $v )
{
$array[ $v ] = $v;
}
echo '<pre>'.print_r( $array, true ).'</pre>';
Using explode() and array_combine():
$str = "a,b,c";
$array = explode(',', $str);
$array = array_combine($array, $array);
If I have a string like:
123*23*6594*2*-10*12
How can I extract the single numbers, in the string separated by *? That is, I want this output:
a=123, b=23, c=6594, d=2, e=-10, f=12.
Flexible:
$vars = range('a', 'z');
$vals = explode('*', $string);
$result = array_combine(array_slice($vars, 0, count($vals)), $vals);
Result:
Array
(
[a] => 123
[b] => 23
[c] => 6594
[d] => 2
[e] => -10
[f] => 12
)
Just for the sheer fun of setting the result as an iterable (rather than an actual array) with the alpha keys in a slightly different manner:
$data = '123*23*6594*2*-10*12';
function dataseries($data) {
$key = 'a';
while (($x = strpos($data, '*')) !== false) {
yield $key++ => substr($data, 0, $x);
$data = substr($data, ++$x);
}
yield $key++ => $data;
}
foreach(dataseries($data) as $key => $value) {
echo $key, ' = ', $value, PHP_EOL;
}
Requires PHP >= 5.5.0
You can use simple as this :
$str = "123*23*6594*2*-10*12";
$arr = explode("*",$str);
$arr['a']=$arr[0];
$arr['b']=$arr[1];
$arr['c']=$arr[2];
$arr['d']=$arr[3];
$arr['e']=$arr[4];
$arr['f']=$arr[5];
echo "a=" .$arr['a'] ." b=". $arr['b']." c=". $arr['c']." d=". $arr['d']." e=". $arr['e']." f=". $arr['f'];
EDIT:
To accomplish Rizier123 wish :
$str = "123*23*6594*2*-10*12";
$arr = explode("*",$str);
$vars = range('a', 'z');
foreach ($arr as $val => $key){
echo $vars[$val]."=".$key."<br>";
}
something like:
list($a,$b,$c,$d,$e,$f) = explode("*", $str);
Just a guess ;)
I have a string which is like 1,2,2,3,3,4 etc. First of all, I want to make them into groups of strings like (1,2),(2,3),(3,4). Then how I can make this string to array like{(1,2) (2,3) (3,4)}. Why I want this is because I have a array full of these 1,2 etc values and I've put those values in a $_SERVER['query_string']="&exp=".$exp. So Please give me any idea to overcome this issue or solve.Currently this is to create a group of strings but again how to make this array.
function x($value)
{
$buffer = explode(',', $value);
$result = array();
while(count($buffer))
{
$result[] = sprintf('%d,%d', array_shift($buffer), array_shift($buffer));
}
return implode(',', $result);
}
$result = x($expr);
but its not working towards my expectations
I'm not sure I completely understand. You can create pairs of numbers like:
$string = '1,2,3,4,5,6';
$arr = array_chunk(explode(',', $string), 2);
This will give you something like:
array(
array(1, 2),
array(3, 4),
array(5, 6)
)
If you wanted to turn them into a query string, you'd use http_build_query with some data massaging.
Edit: You can build the query like this (100% UNtested):
$numbers = array_map(function($pair) {
return array($pair[0] => $pair[1]);
}, $arr);
$query_string = '?' . http_build_query($numbers);
This:
echo '<pre>';
$str = '1,2,3,4,5,6,7,8';
preg_match_all('/(\d+,\d+)(?=,*)/', $str, $matches);
$pairs = $matches[0];
print_r($pairs);
Outputs:
Array
(
[0] => 1,2
[1] => 3,4
[2] => 5,6
[3] => 7,8
)