I have a string like this:-
$a = " [abc,hjhd],[ccdc,cdc],[csc,vdfv]";
I want to insert this string into an array.
$marker_tower_line = array(
'type' => 'Feature',
'properties' => array(
'marker-color' => '#f00',
'marker-size' => 'small'
),
'geometry' => array(
'type' => 'LineString',
'coordinates' => array (
$a
)
)
);
The output coming is-
["[abc,hjhd],[ccdc,cdc],[csc,vdfv]"];
But I need-
[[abc,hjhd],[ccdc,cdc],[csc,vdfv]];
The most Simplest answer (one-liner with simple php functions):-
<?php
$a = " [abc,hjhd],[ccdc,cdc],[csc,vdfv]";
$b = array_chunk(explode(",",str_replace(array("[","]"),array("",""),trim($a))),2);
print_r($b);
Output:- https://eval.in/833862
Or a bit more shorten (without trim()):-
<?php
$a = " [abc,hjhd],[ccdc,cdc],[csc,vdfv]";
$b = array_chunk(explode(",",str_replace(array("[","]"," "),array("","",""),$a)),2);
print_r($b);
Output:- https://eval.in/833882
i think you are looking for this,
$somearray=explode(",",$a);
then use $somearray for coordinates. The only catch is that you have to use this idea to implement in your logic.For example if $a is the string that you are making then make it like this,
$a = "[abc,hjhd].,[ccdc,cdc].,[csc,vdfv]";
and then use explode as
$somearray=explode(".,",$a);
hope this helps.
You can use this code. The function make_my_array() will work for any string encoded in your given format.
The make_my_array() function takes your string as parameter and iterates through every character to make your output array. It determines staring of a set by '[' character and determines separate set elements by ',' character and the ']' character determines end of a set.
function make_my_array($sa) {
$s = "";
$ans = array();
for($i=0; $i<strlen($sa); $i++) {
$t = array();
if($sa[$i] == '[') {
for($j=$i+1; $j<strlen($sa); $j++) {
if($sa[$j] == ',') {
$t[] = $s;
$s = "";
}
else if($sa[$j] == ']') {
$t[] = $s;
$s = "";
$i = $j + 1;
$ans[] = $t;
break;
}
else {
$s .= $sa[$j];
}
}
}
}
return $ans;
}
$a = " [abc,hjhd],[ccdc,cdc],[csc,vdfv]";
$marker_tower_line = array(
'type' => 'Feature',
'properties' => array(
'marker-color' => '#f00',
'marker-size' => 'small'
),
'geometry' => array(
'type' => 'LineString',
'coordinates' => make_my_array($a)
)
);
Related
I need elements of array 1 that are not present in array 2 based on the 'value' key only.
Array1
$array1 = array(
array('value' => 113214, 'revision_id' => 2047152),
array('value' => 236462, 'revision_id' => 2045678),
array('value' => 236541, 'revision_id' => 2047155)
);
Array2
$array2 = array(
array('value' => 113214, 'revision_id' => 2047152),
array('value' => 236461, 'revision_id' => 2047153),
array('value' => 236541, 'revision_id' => 2047155)
);
I need the output as below, the difference of arrays should be based on Value
$output = array(
array('value' => 236462, 'revision_id' => 2045678)
);
Just do a nested foreach loop and check the condition hope its helps you :
$arraycheck= array();
foreach($newData as $data1) {
$duplicatecheck = false;
foreach($oldData as $data2) {
if($data1['value'] === $data2['value'] && $data1['revision_id'] === $data2['revision_id']) $duplicatecheck = true;
}
if($duplicatecheck === false) $arraycheck[] = $data1;
}
First, use array_column to get the values of 'value' from array2 into a one-dimensional array:
$a2values = array_column($array2, 'value');
Then use those values to array_filter array1.
$result = array_filter($array1, function($item) use ($a2values) {
// only keep items with values not in array2
return !in_array($item['value'], $a2values);
});
You can use array_udiff which accepts last parameter as callback, and you can define your comparison there easily.
$array1 = [
['value' => '113214', 'revision_id' => '2047152'],
['value' => '236462', 'revision_id' => '2045678'],
['value' => '236541', 'revision_id' => '2047155'],
];
$array2 = [
['value' => '113214', 'revision_id' => '2047152'],
['value' => '236461', 'revision_id' => '2047153'],
['value' => '236541', 'revision_id' => '2047155'],
];
$result = array_udiff ($array1, $array2, function($x, $y) {
return $x['value'] - $y['value'];
});
print_r($result);
taken from: https://gist.github.com/wrey75/c631f6fe9c975354aec7
function my_array_diff($arr1, $arr2) {
$diff = array();
// Check the similarities
foreach( $arr1 as $k1=>$v1 ){
if( isset( $arr2[$k1]) ){
$v2 = $arr2[$k1];
if( is_array($v1) && is_array($v2) ){
// 2 arrays: just go further...
// .. and explain it's an update!
$changes = self::diff($v1, $v2);
if( count($changes) > 0 ){
// If we have no change, simply ignore
$diff[$k1] = array('upd' => $changes);
}
unset($arr2[$k1]); // don't forget
}
else if( $v2 === $v1 ){
// unset the value on the second array
// for the "surplus"
unset( $arr2[$k1] );
}
else {
// Don't mind if arrays or not.
$diff[$k1] = array( 'old' => $v1, 'new'=>$v2 );
unset( $arr2[$k1] );
}
}
else {
// remove information
$diff[$k1] = array( 'old' => $v1 );
}
}
// Now, check for new stuff in $arr2
foreach( $arr2 as $k=>$v ){
// OK, it is quite stupid my friend
$diff[$k] = array( 'new' => $v );
}
return $diff;
}
usage:
$diff = my_array_diff($arr1, $arr2);
var_dump($diff);
This is quite basic, but I am missing a puzzle piece.
I have a multidimensional PHP array that - among other things - contains some strings. I would like to translate special strings in this array based on a translation table or array in PHP.
$r = array(
0 => 'something',
1 => array(
'othertext' => '1000 {{animals}} and {{cars}}',
'anytext' => '400 {{cars}}',
)
);
In $r, now I would like to replace {{animals}} with another string that is stored in a separate array.
Here it is:
$translations = array(
'animals' => array('Tiere','animaux','bestie'),
'cars' => array('Autos','voitures','macchine'),
);
Now let's set the language / column we want to look up
$langId = 0;
And now, take $r, look for all key that are wrapped in {{}}, look them up in $translations and replace them with key[$langId], so in return we get:
$r = array(
0 => 'something',
1 => array(
'othertext' => '1000 Tiere',
'anytext' => '400 Autos',
)
);
ehm... how's that done?
PS: the marker {{}} is random, could be anything robust
I was able to get the output you expected using the following code. Try it and tell me if it worked for you or not:
<?php
$r = array(
0 => 'something',
1 => array(
'othertext' => '1000 {{animals}} and {{cars}}',
'anytext' => '400 {{cars}}',
)
);
$translations = array(
'animals' => array('Tiere','animaux','bestie'),
'cars' => array('Autos','voitures','macchine'),
);
$langId = 0;
$pattern = "/\{\{[a-zA-Z]+\}\}/";
for($t=0; $t<count($r); $t++) {
$row = $r[$t];
if(!is_array($row))
continue;
foreach($row as $key=>$value) {
if(preg_match_all($pattern, $value, $match, PREG_SET_ORDER)) {
for($i = 0; $i < count($match); $i++) {
//remove {{ & }} to get key
$k = substr($match[$i][0], 2, strlen($match[$i][0])-4);
$replacer = $translations[$k][$langId];
$value = str_replace($match[$i][0], $replacer, $value);
$r[$t][$key] = $value;
}
}
}
}
?>
I've tried this with usort, but I didn't succeed.
I've the following array:
array(
[0] => array(
'date' => '3:6:2012'
),
[1] => array(
'date' => '5:5:2012'
),
[2] => array(
'date' => '20:12:2011'
)
)
The date is in d:m:yyyy format, so no leading zero's.
I want to sort the array to get this:
array(
[0] => array(
'date' => '20:12:2011'
),
[1] => array(
'date' => '5:5:2012'
),
[2] => array(
'date' => '3:6:2012'
)
)
I've tried it this way:
function cmp($a, $b) {
if($a['date'] = $b['date']) {
return 0;
}
$partsa = explode(":", $a['date']);
$partsb = explode(":", $b['date']);
$daya = $partsa[0];
$montha = $partsa[1];
$yeara = $partsa[2];
$dayb = $partsb[0];
$monthb = $partsb[1];
$yearb = $partsb[2];
if($yeara < $yearb) {
return -1;
} elseif($yeara > $yearb) {
return 1;
} elseif($yeara == $yearb) {
if($montha < $monthb) {
return -1;
} elseif($montha > $monthb) {
return 1;
} elseif($montha == $monthb) {
if($daya < $dayb) {
return -1;
} elseif($daya > $dayb) {
return 1;
} elseif($daya == $dayb) {
return 0;
}
}
}
}
but this doesn't give good results with usort...
How to do this?
You can create a temporary array with normalized dates (yyyymmdd), then use array_multisort:
$arr = array(
array(
'date' => '3:6:2012'
),
array(
'date' => '5:5:2012'
),
array(
'date' => '20:12:2011'
),
array(
'foo' => 'no date here'
),
);
foreach($arr as $key=>$row) {
if(isset($row['date'])) {
$date = explode(':',$row['date']);
$date = $date[2] . str_pad($date[1],2,'0',STR_PAD_LEFT) . str_pad($date[0],2,'0',STR_PAD_LEFT);
$sort_arr[$key] = $date;
} else {
$sort_arr[$key] = null;
}
}
array_multisort($sort_arr, SORT_ASC, $arr);
print_r($arr);
PHP offers the function strcmp, that's doing the comparing stuff for us. In order to compare the dates correctly, we create timestamp out of it.
But at first we need to parse the string: exploding by : and finally throwing them to mktime.
function cmp($a, $b) {
$a = explode(':', $a['date']);
$a = mktime(0, 0, 0, intval($a[1]), intval($a[0]), intval($a[2]));
$b = explode(':', $b['date']);
$b = mktime(0, 0, 0, intval($b[1]), intval($b[0]), intval($b[2]));
return strcmp($a, $b);
}
Note: The first three arguments of mktime are hours, minutes and seconds and can be ignored in this scenario.
First, make them dates (normal, php-readable dates):
foreach($array as $innerarray){
foreach($innerarray as $key=>$value){
$date = explode(":", $value);
$date = date($date[2]."/".$date[1]."/".$date[0]);
$array[$innerarray][$key] = $date;
}
}
After this, you can sort them with the following function:
function sort_bydate($a, $b) {
return strnatcmp($a['date'], $b['date']);
}
// sort by date
usort($data, 'sort_bydate');
This should do the trick.
By the way, I would advise to not use arrays in arrays, because it is useless in your case.
I wanna know how to sort arrays like this:
$array[] = Array (
'name' => '/home/gtsvetan/public_html/presta/cms.php'
'type' => 'text/x-php'
'size' => 1128
'lastmod' => 1339984800
);
$array[] = Array (
'name' => '/home/gtsvetan/public_html/presta/docs/'
'type' => 'dir'
'size' => 0
'lastmod' => 1329253246
);
I wanna to sort it first by type (folders first and then files) and then alphabetical. But I don't know how to sort it.
Best regards,
George!
you can use usort()
In compare function you do two comparisions on name & type - something like below:
function compare_f($a,$b) {
if($a['type']=='dir'&&$b['type']!='dir') return 1;
if($a['type']!='dir'&&$b['type']=='dir') return -1;
if(substr($a['name'],-1,1)=='/') $a['name']=substr($a['name'],0,-1);
if(substr($b['name'],-1,1)=='/') $b['name']=substr($b['name'],0,-1);
$af_array=explode('/',$a['name']);
$a_name=$af_array[count($af_array)-1];
$bf_array=explode('/',$b['name']);
$b_name=$bf_array[count($bf_array)-1];
if($a_name>$b_name)
return 1;
return -1;
}
usort($array,'compare_f');
You can do something like this..
$dir = array();
$file = array();
$dir = array();
$file = array();
foreach($array as $b=>$v) {
if($v['type'] == "dir") {
$dir[] = $v;
} else {
$file[] = $v;
}
}
$combined = array_merge($dir, $file);
Feel free to adjust it.
This is sort of a general implementation question. If I have an arbitrarily deep array, and I do not know before hand what the keys will be, what is the best way to access the values at specific paths of the associative array? For example, given the array:
array(
'great-grandparent' = array(
'grandparent' = array(
'parent' = array(
'child' = 'value';
),
'parent2' = 'value';
),
'grandparent2' = 'value';
)
);
Whats the best way to access the value at $array['great-grandparent']['grandparent']['parent']['child'] keeping in mind that I don't know the keys beforehand. I have used eval to construct the above syntax as a string with variable names and then eval'd the string to get the data. But eval is slow and I was hoping for something faster. Something like $class->getConfigValue('great-grandparent/grandparent/'.$parent.'/child'); that would return 'value'
Example of Eval Code
public function getValue($path, $withAttributes=false) {
$path = explode('/', $path);
$rs = '$r = $this->_data[\'config\']';
foreach ($path as $attr) {
$rs .= '[\'' . $attr . '\']';
}
$rs .= ';';
$r = null;
#eval($rs);
if($withAttributes === false) {
$r = $this->_removeAttributes($r);
}
return $r;
}
I don't know about the potential speed but you don't need to use eval to do a search like that :
$conf = array(
'great-grandparent' => array(
'grandparent' => array(
'parent' => array(
'child' => 'value searched'
),
'parent2' => 'value'
),
'grandparent2' => 'value'
)
);
$path = 'great-grandparent/grandparent/parent/child';
$path = explode('/', $path);
$result = $conf;
while(count($path) > 0) {
$part = array_shift($path);
if (is_array($result) && array_key_exists($part, $result)) {
$result = $result[$part];
} else {
$result = null;
break;
}
}
echo $result;
Here we go, my solution:
$tree = array(
'great-grandparent' => array(
'grandparent' => array(
'parent' => array(
'child' => 'value1'
),
'parent2' => 'value2'
),
'grandparent2' => 'value3'
)
);
$pathParts = explode('/','great-grandparent/grandparent/parent/child');
$pathParts = array_reverse($pathParts);
echo retrieveValueForPath($tree, $pathParts);
function retrieveValueForPath($node, $pathParts) {
foreach($node as $key => $value) {
if(($key == $pathParts[count($pathParts)-1]) && (count($pathParts)==1)) {
return $value;
}
if($key == $pathParts[count($pathParts)-1]) {
array_pop($pathParts);
}
if(is_array($value)) {
$result = retrieveValueForPath($value, $pathParts);
}
}
return $result;
}