PHP: Parsing data within multidimensional array - php

I have an array which looks like this:
Array
(
[0] => Array
(
[0] => TE=140414100000 cd =AB1234 ggg =1234567 gbh =2
[7] => nd: DA1AAAAAAAAAA: TD = 140414:
)
[1] => Array
(
[0] => TE=140414100000 cd =AB1234 ggg =1234567 ghb =2
[7] => nd: DA1AAAAAAAAAA: TD = 140414:
)
)
what I am trying to acomplish is to parse data within each sub array and create a new multidimensional array with the parsed data.
Example: the data in parentheses below is what should be returned in new multidimensional array
Array
(
[0] => Array
(
[0] => te=(140414100000) cd =AB(1234) ggg =1234567 ghb =2
[7] => nd: DA(1)(AAAAAAAAAA): TD = (140414):
)
[1] => Array
(
[0] => te=(140414100000) cd =AB(1234) ggg =1234567 ghb =2
[7] => nd: DA(2)(BBBBBBBBBB): TD = (140414):
)
)
What I want to return:
Array
(
[0] => Array
(
[0] => 140414100000
[1] => 1234
[2] => 1
[3] => AAAAAAAAAA
[4] => 140414
)
[1] => Array
(
[0] => 140414100000
[1] => 1234
[2] => 2
[3] => BBBBBBBBBB
[4] => 140414
)
).
So my question is what would be the best way to acomplish this?
This is what I have come up with. It works, however is seems very inefficient as it adds a lot of empty arrays which have to be cleaned up.
foreach($new as $key => $val){
foreach($val as $res){
preg_match_all('%te=([0-9]{12})\s%',$res,$matches);
$out[$key][] = $matches[1][0];
preg_match_all('%cd\s+=AB([0-9]{4})%',$res,$matches);
$out[$key][] = $matches[1][0];
preg_match_all('%nd:\sDA([0-9]{1})%',$res,$matches);
$out[$key]['node'] = $matches[1][0];
preg_match_all('%nd:\sDA[0-9]{1}([a-zA-Z]{10,14}):%',$res,$matches);
$out[$key]['rset'] = $matches[1][0];
preg_match_all('%td\s=\s([0-9]{6}):%',$res,$matches);
$out[$key]['trdt'] = $matches[1][0];
}
}
foreach($out as $v){
$v = array_values(array_filter($v));
$return[] = $v;
}
return $return;
Thanks in advance.
UPDATED:
This worked and is much more efficient. Thanks for the example Shankar
foreach($new as $key => $val){
$v = implode('', $val);
preg_match_all("%te=([0-9]{12})|cd\s+=AB([0-9]{4})|nd:\sDA([0-9]{1})|([A-Z]{3,7}):|td=\s([0-9]{6}):%",$v,$matches);
$new_array[$key]['time'] = $matches[1][0];
$new_array[$key]['code'] = $matches[2][1];
$new_array[$key]['sp'] = $matches[3][2];
$new_array[$key]['rset'] = $matches[4][3];
$new_array[$key]['trfdt'] = $matches[5][4];
}
echo "<pre>";
print_r($new_array);
echo "</pre>";

Loop through your array and implode each array element and use a preg_match_all() to capture all the entries bewteen ( and ) and then pass those matches to your new array.
foreach($arr as $k=>$arr1)
{
$v = implode('',$arr1);
preg_match_all('^\((.*?)\)^', $v, $matches);
$new_arr[]=$matches[1];
}
print_r($new_arr);
Working Demo

Related

How to check duplicate value inside foreach loop

I have 3 array like this from foreach loop
$link = 'https://example.com/page/';
$parse = explode('/', $link);
for ($i = 0;$i <= 5;$i++)
{
if($i > 0) {
$link = $parse[0]."//".$parse[1]."/".$parse[2]."/".$parse[3]."/".$parse[4].$i;
$get[$i] = curl($link);
$re = '/class="img-lazy" src="(.*?)"/m';
preg_match_all($re, $get[$i], $matches);
foreach ($matches[1] as $content)
{
echo $content. "\r\n";
}
}
}
(loop from each page eg: example.com/page/1 will contain the array below and so on with page 2/3...)
Result:
Array (Page 1)
(
[0] => https://example.com/img1.jpg
[1] => https://example.com/img2.jpg
)
Array (Page 2)
(
[0] => https://example.com/img3.jpg
[1] => https://example.com/img4.jpg
)
Array (Page 3 nonexist auto redirect to page 1)
(
[0] => https://example.com/img1.jpg
[1] => https://example.com/img2.jpg
)
The last one is duplicate. How do i remove it ?
I already tried to merge the array and array_unique function. But the duplicate one still there.
Quick solution run for loop only 5 times if loop is dynamic follow this answer
What I did is compare very first link. if it repeat then exit.
I checked and it works fine
your images are nice :-)
$get = array();
$firstcompare = 0;
$firsttime = 1;
for ($i = 0;$i <= 17;$i++)
{
if($i > 0) {
$dup = $res = [];
$link = $parse[0]."//".$parse[1]."/".$parse[2]."/".$parse[3]."/".$parse[4].$i;
$get[$i] = curl($link);
$re = '/class="aligncenter" src="(.*?)"/m';
preg_match_all($re, $get[$i], $matches);
if($firsttime){
$stringlink = $matches[1][0];
$firsttime = 0;
}
foreach ($matches[1] as $content)
{
if($firstcompare){
if ($stringlink==$content) {
exit;
}else{
// echo $content."\n\n";
echo "<img src=' $content ' /> " . "\r\n";
}
}else{
// echo $content."\n\n";
$firstcompare = 1;
echo "<img src=' $content ' /> " . "\r\n";
}
}
}
}
You may try like this as per yourArray, hope it will help you
Using Foreach:
$dup = $res = [];
foreach($yourArray as $arr){
$imploded = #implode(',',$arr);
if(!in_array($imploded, $dup)){
$dup[] = $imploded;
$res[] = $arr;
}
}
(or)
Using Array Function:
$unique = array_unique(array_map(function($arr){
return #implode(',',$arr);
}, $yourArray));
$mapped = array_map(function($a){
return #explode(',', $a);
}, $unique_data);
I don't really understand everything but to remove duplicate data inside an array you can use the array_unique() function.
foreach(array_unique($yourArray) as $value):
// Code goes here
endforeach;
It takes the array and return the clean one
https://www.php.net/manual/fr/function.array-unique.php
Here is the best way to remove duplicate values from the multi-dimensional array by using PHP or Laravel.
Solution:
$input = array_map("unserialize", array_unique(array_map("serialize", $input)));
$input = Array
(
[0] => Array
(
[0] => abc
[1] => def
)
[1] => Array
(
[0] => ghi
[1] => jkl
)
[2] => Array
(
[0] => mno
[1] => pql
)
[3] => Array
(
[0] => abc
[1] => def
)
[4] => Array
(
[0] => ghi
[1] => jkl
)
[5] => Array
(
[0] => mno
[1] => pql
)
)
$input = array_map("unserialize", array_unique(array_map("serialize", $input)));
Output :
Array
(
[0] => Array
(
[0] => abc
[1] => def
)
[1] => Array
(
[0] => ghi
[1] => jkl
)
[2] => Array
(
[0] => mno
[1] => pql
)
[3] => Array
(
[0] => ghi
[1] => jkl
)
[4] => Array
(
[0] => mno
[1] => pql
)
)

convert a string to multi dimensional array in php

I'm having trouble converting a string to a multi-dimensional array in php. This is my string:
$String = a,b,c|d,e,f|g,h,y|
This is what I'm trying:
$one=explode("|",$String);
foreach ($one as $item)
{
$one=explode(",",$one);
}
I'd like to create this array:
$array={ {a,b,c}, {d,e,f}, {g,h,y} };
Try with -
$one=explode("|",$String);
$array = array();
foreach ($one as $item){
$array[] = explode(",",$item);
}
Try this code:
$string = 'a,b,c|d,e,f|g,h,y|';
$arr = array_map(function($iter){ return explode(',',$iter);},explode('|',$string));
Hope it help a bit.
You have almost done it right, except for the cycle part. Try this
$result = [];
$String = 'a,b,c|d,e,f|g,h,y|';
$firstDimension = explode('|', $String); // Divide by | symbol
foreach($firstDimension as $temp) {
// Take each result of division and explode it by , symbol and save to result
$result[] = explode(',', $temp);
}
print_r($result);
Try this-
$String = 'a,b,c|d,e,f|g,h,y|';
$one = array_filter(explode("|", $String));
print_r($one); //Array ( [0] => a,b,c [1] => d,e,f [2] => g,h,y )
$result = array_map('v', $one);
function v($one) {
return explode(',',$one);
}
print_r($result); // Array ( [0] => Array ( [0] => a [1] => b [2] => c ) [1] => Array ( [0] => d [1] => e [2] => f ) [2] => Array ( [0] => g [1] => h [2] => y ) )
Use this code
$String= 'a,b,c|d,e,f|g,h,y|';
$one=explode("|",$String);
print_r(array_filter($one));
Output will be
Array
(
[0] => a,b,c
[1] => d,e,f
[2] => g,h,y
)

php - rearranging an array into groups

I have an array of filenames:
Array
(
[2] => 1_1_page2-img1.jpg
[3] => 1_2_page2-img1-big.jpg
[4] => 2_1_page2-img1.jpg
[5] => 2_2_page2-img1-big.jpg
[6] => 3_1_page2-img1.jpg
[7] => 4_1_page2-img1.jpg
[8] => 4_2_page2-img1.jpg
[9] => 5_2_page2-img1.jpg
)
I'm trying to rearrange them so they're grouped together by their first number. I'm guessing I could maybe separate them with a pipe so I could then distinguish them afterwards. Either that or a multidimensional array.
I know I can perform an explode("_",$filename); to get the first and second digits before the underscores.
The catch is even though the beginning numbers should always increment, there won't necessarily be 2 files per initial number.
So I'm either trying to make it into the following:
Array
(
[0] => 1_1_page2-img1.jpg|1_2_page2-img1-big.jpg
[1] => 2_1_page2-img1.jpg|2_2_page2-img1-big.jpg
[2] => 3_1_page2-img1.jpg|
[3] => 4_1_page2-img1.jpg|4_2_page2-img1.jpg
[4] => |5_2_page2-img1.jpg
)
Or something a bit tidier perhaps? I just can't work out the foreach to put them together.
Or is there an array related command that will put them together easier?
My preference would be to store them in subarrays, as this will be much easier to deal with in the long run; so this would be a possibility, given your array is in $arr:
$newarr = array ();
while (list($key, $val) = each($arr)) {
$subarray_index = substr($val, 0, strpos($val, "_"));
$newarr[$subarray_index][] = $val;
}
Is this what you mean?
$arr = Array(
2 => '1_1_page2-img1.jpg',
3 => '1_2_page2-img1-big.jpg',
4 => '2_1_page2-img1.jpg',
5 => '2_2_page2-img1-big.jpg',
6 => '3_1_page2-img1.jpg',
7 => '4_1_page2-img1.jpg',
8 => '4_2_page2-img1.jpg',
9 => '5_2_page2-img1.jpg'
);
function orderArray($pArr){
$first = '0';
$newArr = array();
foreach($pArr as $val){
if(strpos($val,$first) !== 0){
if(substr($val,2,1)==='1'){
$newArr[]=$val;
}else{
$newArr[]='|'.$val;
}
$first = substr($val,0,1);
}else{
$curIndex = count($newArr) - 1;
$newArr[$curIndex] = $newArr[$curIndex].'|'.$val;
}
return $newArr;
}
$result = orderArray($arr);
print "number of values: ".count($result)."<br>";
foreach($result as $value){
print $value."<br>";
}
Just worked it out now based on another post in stackoverflow:
foreach ($scanned_directory as $filename){
$ids = explode("_",$filename);
$groups[$ids[0]][] = $filename;
}
echo "<pre>";
ksort($groups);
print_r($groups);
echo "</pre>";
Displays:
Array
(
[1] => Array
(
[0] => 1_1_page2-img1.jpg
[1] => 1_2_page2-img1-big.jpg
)
[2] => Array
(
[0] => 2_1_page2-img1.jpg
[1] => 2_2_page2-img1-big.jpg
)
[3] => Array
(
[0] => 3_1_page2-img1.jpg
[1] => 3_2_page2-img1-big.jpg
)
[10] => Array
(
[0] => 10_1_page2-img1.jpg
)
[11] => Array
(
[0] => 11_2_page2-img1-big.jpg
)
)
There isn't a nice automated way of doing this, but you could use a simple loop:
$array = [];
foreach ($filename as $file) {
$fields = explode('_', $file);
$array[$fields[0]][$fields[1]] = $file;
}
An example is located here.

Getting values from array

I know this is a newbie question,
I extracted some preformatted json out of javascript, that looks like this:
[[[455837.99,2896882.36],[455862.44,2896888.35],[455868.79,2896860.14],[455864.3,2896852.78],[455845.76,2896848],[455837.99,2896882.36]]]
I tried an online formatted that shows me the array looks something like this:
Array
(
[0] => Array
(
[0] => Array
(
[0] => 455837.99
[1] => 2896882.36
)
[1] => Array
(
[0] => 455862.44
[1] => 2896888.35
)
[2] => Array
(
[0] => 455868.79
[1] => 2896860.14
)
[3] => Array
(
[0] => 455864.3
[1] => 2896852.78
)
[4] => Array
(
[0] => 455845.76
[1] => 2896848
)
[5] => Array
(
[0] => 455837.99
[1] => 2896882.36
)
)
)
All the third [0]'s are what I need as an X, so everything that starts with 455. and All the [1]'s are the Y's. I would like these two to be grouped together, the respective X and Y.
My problem is I am not sure how to access them out of the area, I have tried this:
preg_match_all('/\[{3}.*\]{3}/', $data, $matches);
$arr=array();
foreach ($matches[0] as $match)
{
$arr[]=json_decode($match);
}
echo '<br>';
$newmatch = json_decode($match);
I would really appreciate if someone can point me in the direction of being able to have a loop that basically echo's the X and Y values, whenever I try and echo something from the array I get:
1) Array to string conversion
I am not sure if that is because of the triple brackets, that its an array in an array in an array.
$data = "[[[455837.99,2896882.36],[455862.44,2896888.35],[455868.79,2896860.14],[455864.3,2896852.78],[455845.76,2896848],[455837.99,2896882.36]]]";
$data_array = json_decode($data);
if (is_array($data_array) && array_key_exists(0, $data_array)) {
foreach ($data_array[0] as $element) {
$x = array_key_exists(0, $element) ? $element[0] : "N/A";
$y = array_key_exists(1, $element) ? $element[1] : "N/A";
printf("X: %s | Y: %s\n", $x, $y);
}
}

PHP Group array by values

I have an array like this:
Array (
[0] => ing_1_ing
[1] => ing_1_amount
[2] => ing_1_det
[3] => ing_1_meas
[4] => ing_2_ing
[5] => ing_2_amount
[6] => ing_2_det
[7] => ing_2_meas
)
And I want to group the values into an array like this:
Array (
[0] => Array(
[0] => ing_1_ing
[1] => ing_1_amount
[2] => ing_1_det
[3] => ing_1_meas
)
[1] => Array(
[0] => ing_2_ing
[1] => ing_2_amount
[2] => ing_2_det
[3] => ing_2_meas
)
)
There may be many other items named like that: ing_NUMBER_type
How do I group the first array to the way I want it? I tried this, but for some reason, strpos() sometimes fails:
$i = 1;
foreach ($firstArray as $t) {
if (strpos($t, (string)$i)) {
$secondArray[--$i][] = $t;
} else {
$i++;
}
}
What is wrong? Can you advice?
It depends what you are trying to achieve, if you want to split array by chunks use array_chunk method and if you are trying to create multidimensional array based on number you can use sscanf method in your loop to parse values:
$result = array();
foreach ($firstArray as $value)
{
$n = sscanf($value, 'ing_%d_%s', $id, $string);
if ($n > 1)
{
$result[$id][] = $value;
}
}
<?php
$ary1 = array("ing_1_ing","ing_1_amount","ing_1_det","ing_1_meas","ing_2_ing","ing_2_amount","ing_2_det","ing_2_meas");
foreach($ary1 as $val)
{
$parts = explode("_",$val);
$ary2[$parts[1]][]=$val;
}
?>
This creates:
Array
(
[1] => Array
(
[0] => ing_1_ing
[1] => ing_1_amount
[2] => ing_1_det
[3] => ing_1_meas
)
[2] => Array
(
[0] => ing_2_ing
[1] => ing_2_amount
[2] => ing_2_det
[3] => ing_2_meas
)
)
What I'd do is something like this:
$result = array();
foreach ($firstArray as $value)
{
preg_match('/^ing_(\d+)_/', $value, $matches);
$number = $matches[1];
if (!array_key_exists($number, $result))
$result[$number] = array();
$result[$number][] = $value;
}
Basically you iterate through your first array, see what number is there, and put it in the right location in your final array.
EDIT. If you know you'll always have the numbers start from 1, you can replace $number = $matches[1]; for $number = $matches[1] - 1;, this way you'll get exactly the same result you posted as your example.

Categories