How Convert Value to Array PHP - php

I'm get data string lat and long google maps polygon. I want to convert this value to array .
$value = "(-6.2811957386588855, 106.70141951079609),(-6.281142416506361, 106.70432702536823),(-6.2781776962328815, 106.70438066954853),(-6.2781776962328815, 106.70136586661579)";
I want the result like this Array :
$polygon = array(
array(-6.2811957386588855, 106.70141951079609),
array(-6.281142416506361, 106.70432702536823),
array(-6.2781776962328815, 106.70438066954853),
array(-6.2781776962328815, 106.70136586661579),
);

You can convert the string to valid JSON by converting parentheses to square brackets and adding a [] layer around the outside, and then json_decode it:
$value = '(-6.2811957386588855, 106.70141951079609),(-6.281142416506361, 106.70432702536823),(-6.2781776962328815, 106.70438066954853),(-6.2781776962328815, 106.70136586661579)';
$polygon = json_decode('[' . str_replace(array('(', ')'), array('[', ']'), $value) . ']', true);
print_r($polygon);
Output:
Array
(
[0] => Array
(
[0] => -6.2811957386589
[1] => 106.7014195108
)
[1] => Array
(
[0] => -6.2811424165064
[1] => 106.70432702537
)
[2] => Array
(
[0] => -6.2781776962329
[1] => 106.70438066955
)
[3] => Array
(
[0] => -6.2781776962329
[1] => 106.70136586662
)
)
Demo on 3v4l.org

Using preg_match_all() and array_walk() you can parse the coordinates as an array
$value = '(-6.2811957386588855, 106.70141951079609),(-6.281142416506361, 106.70432702536823),(-6.2781776962328815, 106.70438066954853),(-6.2781776962328815, 106.70136586661579)';
preg_match_all('/\(([0-9\-\s,.]+)\)/', $value, $matches);
array_walk($matches[1], function(&$val) { $val = explode(',', $val); });
$coordinates = $matches[1];
print_r($coordinates);
Using preg_match_all() get all the coordinates as array of string
Using array_walk() make an iteration over the coordinated array and explode by the delimiter of comma (,)
Working demo.
Regex demo.

You can use explode() function like this
$string = '(-6.2811957386588855, 106.70141951079609),(-6.281142416506361, 106.70432702536823),(-6.2781776962328815, 106.70438066954853),(-6.2781776962328815, 106.70136586661579)';
foreach(explode('),(',trim($string,'()')) as $single_array)
{
$sub_array= array();
foreach(explode(',',$single_array) as $sbs_array)
{
$sub_array[] = $sbs_array;
}
$result[] = $sub_array;
}
print_r ($result);
Output :
Array
(
[0] => Array
(
[0] => -6.2811957386588855
[1] => 106.70141951079609
)
[1] => Array
(
[0] => -6.281142416506361
[1] => 106.70432702536823
)
[2] => Array
(
[0] => -6.2781776962328815
[1] => 106.70438066954853
)
[3] => Array
(
[0] => -6.2781776962328815
[1] => 106.70136586661579
)
)
Demo : https://3v4l.org/6HEAG

You can use explode with trim and array_map
$r = explode('),(',trim($value,'()'));
$c = array_map(function($v){return explode(',',$v);}, $r);
print_r($c);
Working example : https://3v4l.org/fFAS0

I suggest using preg_match_all with array_map
$value = '(-6.2811957386588855, 106.70141951079609),(-6.281142416506361, 106.70432702536823),(-6.2781776962328815, 106.70438066954853),(-6.2781776962328815, 106.70136586661579)';
preg_match_all('#\(([\-\d\.]+),\s+([\-\d\.]+)\)#', $value, $matches);
$geo = array_map(function ($a, $b) {
return [(float)$a, (float)$b];
}, $matches[1], $matches[2]);
Output:
array(4) {
[0]=>
array(2) {
[0]=> float(-6.2811957386589)
[1]=> float(106.7014195108)
}
[1]=>
array(2) {
[0]=> float(-6.2811424165064)
[1]=> float(106.70432702537)
}
[2]=>
array(2) {
[0]=> float(-6.2781776962329)
[1]=> float(106.70438066955)
}
[3]=>
array(2) {
[0]=> float(-6.2781776962329)
[1]=> float(106.70136586662)
}
}
Regex

Related

PHP Transform multiple objects into one array

Whilst trying to transform multiple objects and put them into one array I unfortunately get a array-in-array result.
The objects I would like to transform:
array(2) {
[0]=>
object(stdClass)#104 (1) {
["name"]=>
string(4) "Paul"
}
[1]=>
object(stdClass)#105 (1) {
["name"]=>
string(5) "Jenna"
}
}
My PHP:
for ($i=0; $i < count($readers) ; $i++) {
$json = json_encode($readers[$i]); // 1
$data = json_decode($json, TRUE); // 2
$arr = array();
array_push($arr, $data); // 3
}
The outputs:
// 1
{"name":"Paul"}{"name":"Jenna"}
-
// 2
Array
(
[name] => Paul
)
Array
(
[name] => Jenna
)
-
// 3
Array
(
[0] => Array
(
[name] => Paul
)
)
Array
(
[0] => Array
(
[name] => Jenna
)
)
Desired Outcome
I would like to have everything merged into one array. The key is the index and the value is the name.
Array
(
[0] => Paul
[1] => Jenna
)
Loop through the array of objects ($arr) and compile the final array ($finArr) with the $val->string value. Try this:
$finArr = array();
foreach ($arr as $key => $val) {
$finArr[] = $val->string;
}
You can simply iterate through the array of readers, pull out the name of each reader, and add each of their names to a numerically indexed array as you desire.
$names = array(); // Initialize.
foreach($readers as $reader) {
if (!empty($reader->name)) {
$names[] = $reader->name;
}
}
print_r($names); // To see what you've got.
Array
(
[0] => Paul
[1] => Jenna
)
You have to extract key also from array. And declare $arr = array() outside foreach
$arr = array();
for ($i=0; $i < count($readers) ; $i++) {
$data = $readers[$i]->name; //change this line
array_push($arr, $data); // 3
}
print_r($arr);
Another way is you can simply use array_column()
$arr = array_column($readers,"name");
print_r($arr);

Create multidimensional array from flat file array

I have an array like this:
$arr = array(
'home.js' => new File(),
'view/index.html' => new File(),
'src/index.js' => new File(),
'src/libs/jquery.js' => new File()
);
Now I want to convert in a structure like this:
Array
(
[0] => Array
(
[text] => home.js
)
[1] => Array
(
[text] => view
[children] => Array
(
[0] => Array
(
[text] => index.html
)
)
)
[2] => Array
(
[text] => src
[children] => Array
(
[0] => Array
(
[text] => index.js
)
[1] => Array
(
[text] => libs
[children] => Array
(
[0] => Array
(
[text] => jquery.js
)
)
)
)
)
)
I tried for hours, with help of StackOverfow answers but I couldn't come up with a solution as all other questions have a different setup.
Edit:
What I got so far with the help of SO is (can't remember the exact answer though):
$out = array();
foreach($arr as $path => $file) {
$parts = explode('/', trim($path, '/'));
applyChain($out, $parts, $file);
}
function applyChain(&$arr, $parts, $value)
{
if (!is_array($parts)) {
return;
}
if (count($parts) == 0) {
$arr = $value;
} else {
array_shift($parts);
applyChain($arr[], $parts, $value);
}
}
print_r($out);
I don't know how exactly it works, especially the part applyChain($arr[] ...). It kinda works with the depth, but not with the file names. I get following output:
Array
(
[0] => File Object
(
)
[1] => Array
(
[0] => File Object
(
)
)
[2] => Array
(
[0] => File Object
(
)
)
[3] => Array
(
[0] => Array
(
[0] => File Object
(
)
)
)
)
There would be a solution in a few lines using explode() and eval(). But eval() is not considered clean, so lets try recursion:
<?php
class File {
}
$arr = array(
'home.js' => new File(),
'view/index.html' => new File(),
'src/index.js' => new File(),
'src/libs/jquery.js' => new File()
);
function sub($path) {
$rv = array();
$parts = explode('/', $path, 2); // strip off one level
$rv['text'] = $parts[0]; // put it into 'text' element
if (count($parts)>1) // is there anything left?
$rv['children'] = sub($parts[1]); // do the same for the rest of the path
return $rv;
}
$new = array();
foreach (array_keys($arr) as $file) {
$new[] = sub($file);
}
var_dump($new);
?>
But, as Peter commented, this creates seperate substructures even if the pathes have some part in common (like src/libs/jquery.js and src/libs/melon.js).
With the use of ugly eval() (which can be replaced later) I got the following code:
<?php
class File {
}
$arr = array(
'home.js' => new File(),
'view/index.html' => new File(),
'src/index.js' => new File(),
'src/libs/jquery.js' => new File(),
'src/libs/melon.js' => new File(),
);
// conversion
function sub($element) {
$rv = array();
foreach (array_keys($element) as $sub) {
$part['text'] = $sub;
if (is_array($element[$sub])) {
$part['children'] = sub($element[$sub]);
}
$rv[] = $part;
}
return $rv;
}
// create array with path file/folder names as keys
$new = array();
foreach (array_keys($arr) as $row) {
$def = '$new["'.preg_replace('&/&', '"]["', $row).'"] = 1;';
eval($def);
}
// run
$new2 = sub($new);
var_dump($new2);
?>
This outputs
array(3) {
[0]=>
array(1) {
["text"]=>
string(7) "home.js"
}
[1]=>
array(2) {
["text"]=>
string(4) "view"
["children"]=>
array(1) {
[0]=>
array(1) {
["text"]=>
string(10) "index.html"
}
}
}
[2]=>
array(2) {
["text"]=>
string(3) "src"
["children"]=>
array(2) {
[0]=>
array(1) {
["text"]=>
string(8) "index.js"
}
[1]=>
array(2) {
["text"]=>
string(4) "libs"
["children"]=>
array(2) {
[0]=>
array(1) {
["text"]=>
string(9) "jquery.js"
}
[1]=>
array(1) {
["text"]=>
string(8) "melon.js"
}
}
}
}
}
}

Splitting this multidimensional array

How would I go about splitting this array to access and loop through each of these videos...
array(1) {
[0]=> array(2)
{
[0]=> array(3)
{
["title"]=> string(27) "A test title for this video"
["video_item"]=> string(70) "http://dev.test/wp-content/uploads/2014/01/1.Introduction3.mp4"
["video_image"]=> string(78) "http://dev.test/wp-content/uploads/2014/01/1.Introduction3_thumb23.jpg"
}
[1]=> array(3)
{
["title"]=> string(13) "asdf fads fad"
["video_item"]=> string(67) "http://dev.test/wp-content/uploads/2014/01/Spring-Mower.mp4"
["video_image"]=> string(75) "http://dev.test/wp-content/uploads/2014/01/Spring-Mower1_thumb6.jpg"
}
}
}
This is part of the code I am using but obviously not working
// this gets the array
$videos = get_post_meta( get_the_ID(), 'video_items', false );
$vid = array();
$img = array();
foreach( $videos as $video ) {
$vid[] = $video['video_item'];
$img[] = $video['video_image'];
}
You have an array within an array, so you need to access the first element before you start iterating through each array inside that
So just add this line after you get the array $videos = fullArray[0];
// this gets the array as you did in your original code block
$fullArray = get_post_meta( get_the_ID(), 'video_items', false );
//But then you actually needed to add the below line. This gets the first
//element of the array which happens to be an array and actually contains the array you
//originally wanted to iterate through
$videos = fullArray[0];
$vid = array();
$img = array();
foreach( $videos as $video ) {
$vid[] = $video['video_item'];
$img[] = $video['video_image'];
}
echo "video urls " . $vid . "\n";
echo "image urls " . $img;
Maybe you can use array_chunk to have it's pieces.
http://us2.php.net/manual/en/function.array-chunk.php
As said in the documentation:
<?php
$input_array = array('a', 'b', 'c', 'd', 'e');
print_r(array_chunk($input_array, 2));
print_r(array_chunk($input_array, 2, true));
?>
Will print
Array
(
[0] => Array
(
[0] => a
[1] => b
)
[1] => Array
(
[0] => c
[1] => d
)
[2] => Array
(
[0] => e
)
)
Array
(
[0] => Array
(
[0] => a
[1] => b
)
[1] => Array
(
[2] => c
[3] => d
)
[2] => Array
(
[4] => e
)
)
try this
foreach($array as $key => value)
{
if(is_array($value))
{
foreach($value as $k => $v)ev
{
foreach($v as $k1 => $v1)
{
echo $k1 .'=>'.$v1.PHP_EOL;
}
}
}
}
even better will be using a RecursiveIterator here

Explode comma separated integers to intvals? [duplicate]

This question already has answers here:
Convert a comma-delimited string into array of integers?
(17 answers)
Closed 9 years ago.
Say I have a string like so $thestring = "1,2,3,8,2".
If I explode(',', $thestring) it, I get an array of strings. How do I explode it to an array of integers instead?
array_map also could be used:
$s = "1,2,3,8,2";
$ints = array_map('intval', explode(',', $s ));
var_dump( $ints );
Output:
array(5) {
[0]=> int(1)
[1]=> int(2)
[2]=> int(3)
[3]=> int(8)
[4]=> int(2)
}
Example codepad.
Use something like this:
$data = explode( ',', $thestring );
array_walk( $data, 'intval' );
http://php.net/manual/en/function.array-walk.php
For the most part you shouldn't really need to (PHP is generally good with handling casting strings and floats/ints), but if it is absolutely necessary, you can array_walk with intval or floatval:
$arr = explode(',','1,2,3');
// use floatval if you think you are going to have decimals
array_walk($arr,'intval');
print_r($arr);
Array
(
[0] => 1
[1] => 2
[2] => 3
)
If you need something a bit more verbose, you can also look into settype:
$arr = explode(",","1,2,3");
function fn(&$a){settype($a,"int");}
array_walk($f,"fn");
print_r($f);
Array
(
[0] => 1
[1] => 2
[2] => 3
)
That could be particularly useful if you're trying to cast dynamically:
class Converter {
public $type = 'int';
public function cast(&$val){ settype($val, $this->type); }
}
$c = new Converter();
$arr = explode(",","1,2,3,0");
array_walk($arr,array($c, 'cast'));
print_r($arr);
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 0
)
// now using a bool
$c->type = 'bool';
$arr = explode(",","1,2,3,0");
array_walk($arr,array($c, 'cast'));
var_dump($arr); // using var_dump because the output is clearer.
array(4) {
[0]=>
bool(true)
[1]=>
bool(true)
[2]=>
bool(true)
[3]=>
bool(false)
}
Since $thestring is an string then you will get an array of strings.
Just add (int) in front of the exploded values.
Or use the array_walk function:
$arr = explode(',', $thestring);
array_walk($arr, 'intval');
$thestring = "1,2,3,8,a,b,2";
$newArray = array();
$theArray = explode(",", $thestring);
print_r($theArray);
foreach ($theArray as $theData) {
if (is_numeric($theData)) {
$newArray[] = $theData;
}
}
print_r($newArray);
// Output
Original array
Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 8 [4] => a [5] => b [6] => 2 )
Numeric only array
Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 8 [4] => 2 )
$arr=explode(',', $thestring);
$newstr = '';
foreach($arr as $key=>$val){
$newstr .= $val;
}

Split a string on every third instance of character

How can I explode a string on every third semicolon (;)?
example data:
$string = 'piece1;piece2;piece3;piece4;piece5;piece6;piece7;piece8;';
Desired output:
$output[0] = 'piece1;piece2:piece3;'
$output[1] = 'piece4;piece5;piece6;'
$output[2] = 'piece7;piece8;'
I am sure you can do something slick with regular expressions, but why not just explode the each semicolor and then add them three at a time.
$tmp = explode(";", $string);
$i=0;
$j=0;
foreach($tmp as $piece) {
if(! ($i++ %3)) $j++; //increment every 3
$result[$j] .= $piece;
}
Easiest solution I can think of is:
$chunks = array_chunk(explode(';', $input), 3);
$output = array_map(create_function('$a', 'return implode(";",$a);'), $chunks);
Essentially the same solution as the other ones that explode and join again...
$tmp = explode(";", $string);
while ($tmp) {
$output[] = implode(';', array_splice($tmp, 0, 3));
};
$string = "piece1;piece2;piece3;piece4;piece5;piece6;piece7;piece8;piece9;";
preg_match_all('/([A-Za-z0-9\.]*;[A-Za-z0-9\.]*;[A-Za-z0-9\.]*;)/',$string,$matches);
print_r($matches);
Array
(
[0] => Array
(
[0] => piece1;piece2;piece3;
[1] => piece4;piece5;piece6;
[2] => piece7;piece8;piece9;
)
[1] => Array
(
[0] => piece1;piece2;piece3;
[1] => piece4;piece5;piece6;
[2] => piece7;piece8;piece9;
)
)
Maybe approach it from a different angle. Explode() it all, then combine it back in triples. Like so...
$str = "1;2;3;4;5;6;7;8;9";
$boobies = explode(";", $array);
while (!empty($boobies))
{
$foo = array();
$foo[] = array_shift($boobies);
$foo[] = array_shift($boobies);
$foo[] = array_shift($boobies);
$bar[] = implode(";", $foo) . ";";
}
print_r($bar);
Array
(
[0] => 1;2;3;
[1] => 4;5;6;
[2] => 7;8;9;
)
Here's a regex approach, which I can't say is all too good looking.
$str='';
for ($i=1; $i<20; $i++) {
$str .= "$i;";
}
$split = preg_split('/((?:[^;]*;){3})/', $str, -1,
PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
Output:
Array
(
[0] => 1;2;3;
[1] => 4;5;6;
[2] => 7;8;9;
[3] => 10;11;12;
[4] => 13;14;15;
[5] => 16;17;18;
[6] => 19;
)
Another regex approach.
<?php
$string = 'piece1;piece2;piece3;piece4;piece5;piece6;piece7;piece8';
preg_match_all('/([^;]+;?){1,3}/', $string, $m, PREG_SET_ORDER);
print_r($m);
Results:
Array
(
[0] => Array
(
[0] => piece1;piece2;piece3;
[1] => piece3;
)
[1] => Array
(
[0] => piece4;piece5;piece6;
[1] => piece6;
)
[2] => Array
(
[0] => piece7;piece8
[1] => piece8
)
)
Regex Split
$test = ";2;3;4;5;6;7;8;9;10;;12;;14;15;16;17;18;19;20";
// match all groups that:
// (?<=^|;) follow the beginning of the string or a ;
// [^;]* have zero or more non ; characters
// ;? maybe a semi-colon (so we catch a single group)
// [^;]*;? again (catch second item)
// [^;]* without the trailing ; (to not capture the final ;)
preg_match_all("/(?<=^|;)[^;]*;?[^;]*;?[^;]*/", $test, $matches);
var_dump($matches[0]);
array(7) {
[0]=>
string(4) ";2;3"
[1]=>
string(5) "4;5;6"
[2]=>
string(5) "7;8;9"
[3]=>
string(6) "10;;12"
[4]=>
string(6) ";14;15"
[5]=>
string(8) "16;17;18"
[6]=>
string(5) "19;20"
}
<?php
$str = 'piece1;piece2;piece3;piece4;piece5;piece6;piece7;piece8;';
$arr = array_map(function ($arr) {
return implode(";", $arr);
}, array_chunk(explode(";", $str), 3));
var_dump($arr);
outputs
array(3) {
[0]=>
string(20) "piece1;piece2;piece3"
[1]=>
string(20) "piece4;piece5;piece6"
[2]=>
string(14) "piece7;piece8;"
}
Similar to #Sebastian's earlier answer, I recommend preg_split() with a repeated pattern. The difference is that by using a non-capturing group and appending \K to restart the fullstring match, you can spare writting the PREG_SPLIT_DELIM_CAPTURE flag.
Code: (Demo)
$string = 'piece1;piece2;piece3;piece4;piece5;piece6;piece7;piece8;';
var_export(preg_split('/(?:[^;]*;){3}\K/', $string, 0, PREG_SPLIT_NO_EMPTY));
A similar technique for splitting after every 2 things can be found here. That snippet actually writes the \K before the last space character so that the trailing space is consumed while splitting.

Categories