Breaking up a string into an array, PHP - php

I have a string that looks like this:
$dash_access = "1-10:rw,14:rw|10-10:ro,14:ro";
My goal, is to break this string up into an array. I think I'm close, but can't quite figure it out. I want my array structure to look like this:
$array = Array
(
[1] => Array
(
[10] => rw
[14] => rw
)
[10] => Array
(
[10] => ro
[14] => ro
)
)
This is what I have so far, but it's not working.
$dash_access_split = explode("|",$dash_access);
for ($a=0;$a<count($dash_access_split);$a++) {
$split1 = explode("-", $dash_access_split[$a]);
$split2 = explode(",", $split1[1]);
for ($b=0;$b<count($split2);$b++) {
$split3 = explode(":", $split2[$b]);
$dash_access_array[$split1[0]][] = $split3[0];
$dash_access_array[$split1[0]][] = $split3[1];
}
}

Think of it as crumbling a cookie. Break it into progressively smaller pieces and process each piece accordingly.
Something like this should work
$dashAccess = "1-10:rw,14:rw|10-10:ro,14:ro";
$outArray = [];
foreach (explode('|', $dashAccess) as $bigPiece) {
list($medKey, $medPiece) = explode('-', $bigPiece);
$outArray[$medKey] = [];
foreach (explode(',', $medPiece) as $smallPiece) {
list($crumbleKey, $crumblePiece) = explode(':', $smallPiece);
$outArray[$medKey][$crumbleKey] = $crumblePiece;
}
}
var_dump($outArray);
Here's a fiddle

<?php $dash_access = "1-10:rw,14:rw|10-10:ro,14:ro";
$big_array=explode('|',$dash_access);
$small_array=array();
foreach($big_array as $key=>$value)
{
$small_array[]=explode('-',$value);
foreach($small_array as $key => $value)
{
$chunk=explode(',',$value[1]);
foreach($chunk as $value1)
{
$chunk_small=explode(':',$value1);
$result[$value[0]][$chunk_small[0]]=$chunk_small[1];
}
}
}
print_r($result);
http://codepad.org/sKZyDu2m

Related

Manipulation of php array

I need to create path structure, with the values that I am getting from the array:
Array
(
[machineAttribute] => Array
(
[0] => TTT 1000 S
[1] => TTT 1100 S
)
[technicalAttribute] => Array
(
[0] => Certificate
[1] => Software
)
[languageAttribute] => Array
(
[0] => English
[1] => Spanish
)
)
So, I need to create path that looks like this:
Array
(
[0] => TTT 1000 S/Certificate/English
[1] => TTT 1000 S/Certificate/Spanish
[2] => TTT 1000 S/Software/English
[3] => TTT 1000 S/Software/Spanish
[4] => TTT 1100 S/Certificate/English
[5] => TTT 1100 S/Certificate/Spanish
[6] => TTT 1100 S/Software/English
[7] => TTT 1100 S/Software/Spanish
)
This is a perfect scenario and I was able to solve this with nested foreach:
if (is_array($machineAttributePath))
{
foreach ($machineAttributePath as $machinePath)
{
if (is_array($technicalAttributePath))
{
foreach ($technicalAttributePath as $technicalPath)
{
if (is_array($languageAttributePath))
{
foreach ($languageAttributePath as $languagePath)
{
$multipleMachineValuesPath[] = $machinePath . '/' . $technicalPath . '/' . $languagePath);
}
}
}
}
}
return $multipleMachineValuesPath;
}
But, the problem begins, if the array returns mixed values, sometimes, single value, sometimes array. For example:
Array
(
[machineAttribute] => Array
(
[0] => TTT 1000 S
[1] => TTT 1100 S
[2] => TTT 1200 S
)
[technicalAttribute] => Certificate
[languageAttribute] => Array
(
[0] => English
[1] => Spanish
)
)
Then the array should look like:
Array
(
[0] => TTT 1000 S/Certificate/English
[1] =>TTT 1000 S/Certificate/Spanish
[2] => TTT 1100 S/Certificate/English
[3] => TTT 1100 S/Certificate/Spanish
)
I wrote code, but it is really messy and long and not working properly. I am sure that this could be somehow simplified but I have enough knowledge to solve this. If someone knows how to deal with this situation, please help. Thank you.
You can convert any single value to array just by
(array) $val
In the same time, if $val is already array, it will be not changed
So, you can a little change all foreach
foreach((array) $something....
If you need something simple, you can convert your scalar values to array by writing simple separate function (let name it "force_array"). The function that wraps argument to array if it is not array already.
function force_array($i) { return is_array($i) ? $i : array($i); }
//...
foreach (force_array($machineAttributePath) as $machinePath)
{
foreach (force_array($technicalAttributePath) as $technicalPath)
{
foreach (force_array($languageAttributePath) as $languagePath)
{
$multipleMachineValuesPath[] = $machinePath . '/' . $technicalPath . '/' . $languagePath;
}
}
}
return($multipleMachineValuesPath);
You can do this way also without messing up. Just create the Cartesian of your input array and finally implode the generated array with /. Hope this helps :)
<?php
function cartesian($input) {
$result = array();
while (list($key, $values) = each($input)) {
if (empty($values)) {
continue;
}
if (empty($result)) {
foreach($values as $value) {
$result[] = array($key => $value);
}
}
else {
$append = array();
foreach($result as &$product) {
$product[$key] = array_shift($values);
$copy = $product;
foreach($values as $item) {
$copy[$key] = $item;
$append[] = $copy;
}
array_unshift($values, $product[$key]);
}
$result = array_merge($result, $append);
}
}
return $result;
}
$data = array
(
'machineAttribute' => array
(
'TTT 1000 S',
'TTT 1100 S'
),
'technicalAttribute' => array
(
'Certificate',
'Software'
),
'languageAttribute' => array
(
'English',
'Spanish',
)
);
$combos = cartesian($data);
$final_result = [];
foreach($combos as $combo){
$final_result[] = implode('/',$combo);
}
print_r($final_result);
DEMO:https://3v4l.org/Zh6Ws
This will solve your problem almost.
$arr['machineAttribute'] = (array) $arr['machineAttribute'];
$arr['technicalAttribute'] = (array) $arr['technicalAttribute'];
$arr['languageAttribute'] = (array) $arr['languageAttribute'];
$machCount = count($arr['machineAttribute']);
$techCount = count($arr['technicalAttribute']);
$langCount = count($arr['languageAttribute']);
$attr = [];
for($i=0;$i<$machCount;$i++) {
$attr[0] = $arr['machineAttribute'][$i] ?? "";
for($j=0;$j<$techCount;$j++) {
$attr[1] = $arr['technicalAttribute'][$j] ?? "";
for($k=0;$k<$langCount;$k++) {
$attr[2] = $arr['languageAttribute'][$k] ?? "";
$pathArr[] = implode('/',array_filter($attr));
}
}
}
print_r($pathArr);
This works too!
$results = [[]];
foreach ($arrays as $index => $array) {
$append = [];
foreach ($results as $product) {
foreach ($array as $item) {
$product[$index] = $item;
$append[] = $product;
}
}
$results = $append;
}
print_r(array_map(function($arr){ return implode('/',$arr);},$results));

Combine same indexes of array

I have an array which as dynamic nested indexes in e.g. I am just using 2 nested indexes.
Array
(
[0] => Array
(
[0] => 41373
[1] => 41371
[2] => 41369
[3] => 41370
)
[1] => Array
(
[0] => 41378
[1] => 41377
[2] => 41376
[3] => 41375
)
)
Now I want to create a single array like below. This will have 1st index of first array then 1st index of 2nd array, 2nd index of first array then 2nd index of 2nd array, and so on. See below
array(
[0] =>41373
[1] => 41378
[2] => 41371
[3] => 41377
[4] => 41369
[5] => 41376
[6] => 41370
[7] => 41375
)
You can do something like this:
$results = [];
$array = [[1,2,3,4], [1,2,3,4], [1,2,3,4]];
$count = 1;
$size = count($array)-1;
foreach ($array[0] as $key => $value)
{
$results[] = $value;
while($count <= $size)
{
$results[] = $array[$count][$key];
$count++;
}
$count = 1;
}
I think you need something like this:
function dd(array $arrays): array
{
$bufferArray = [];
foreach($arrays as $array) {
$bufferArray = array_merge_recursive($bufferArray, $array);
}
return $bufferArray;
}
$array1 = ['41373','41371','41369','41370'];
$array2 = ['41378','41377', '41376', '41375'];
$return = array();
$count = count($array1)+count($array2);
for($i=0;$i<($count);$i++){
if($i%2==1){
array_push($return, array_shift($array1));
}
else {
array_push($return, array_shift($array2));
}
}
print_r($return);
first count the arrays in the given array, then count the elements in the first array, than loop over that. All arrays should have the same length, or the first one should be the longest.
$laArray = [
['41373','41371','41369','41370'],
['41378', '41377', '41376', '41375'],
['43378', '43377', '43376', '43375'],
];
$lnNested = count($laArray);
$lnElements = count($laArray[0]);
$laResult = [];
for($lnOuter = 0;$lnOuter < $lnElements; $lnOuter++) {
for($lnInner = 0; $lnInner < $lnNested; $lnInner++) {
if(isset($laArray[$lnInner][$lnOuter])) {
$laResult[] = $laArray[$lnInner][$lnOuter];
}
}
}
this would be the simplest solution:
$firstarr = ['41373','41371','41369','41370'];
$secondarr = ['41378','41377','41376','41375'];
$allcounged = count($firstarr)+count($secondarr);
$dividedintotwo = $allcounged/2;
$i = 0;
while ($i<$dividedintotwo) {
echo $firstarr[$i]."<br>";
echo $secondarr[$i]."<br>";
$i++;
}

Group data by multiple fields dynamically in PHP

I want to group an associative array by fields. The array itself is originally from a mysql database query.
Below is an example of how I do it by hard coding it:
<?php
$fields = array("ID,subID");
$fieldCounts = count($fields);
$data = array(); //there is sql querieed data
$parsedData = array();
foreach ($data as $val)
{
if ($fieldCounts == 1)
{
$f0 = $fields[0];
$fv0 = $val[$f0];
$parsedData[$fv0][] = $val;
}
else if ($fieldCounts == 2)
{
$f0 = $fields[0];
$fv0 = $val[$f0];
$f1 = $fields[10];
$fv1 = $val[$f1];
$parsedData[$fv0][$f1][] = $val;
}
else
{
exit("Third field not implemented");
}
}
?>
But how can I do it dynamically with an arbitrary number of fields?
Am not sure how this code has worked for you but some things are that wrong and might not allow the code to function properly
Fields has only as one valued with ,
$fields = array("ID,subID");
^----------- between string
Instead of
$fields = array("ID","subID");
Notice: Undefined offset:
$f1 = $fields[10];
^----- your array is not up to 10
Since you did not put your generate data and desired output. I would assume your final output and generate some temporary data
$fields = array("ID","subID"); //You can Increase or decrease this Fields
$fieldCounts = count($fields);
$data = array(); // there is sql querieed data
for($i = 0; $i < 3; $i ++) {
$data[] = array("ID" => mt_rand(1, 1000),"subID" => "sub" . mt_rand(100, 900));
}
Ruining your code with the 2 corrections above
foreach ( $data as $val ) {
if ($fieldCounts == 1) {
$f0 = $fields[0];
$fv0 = $val[$f0];
$parsedData[$fv0][] = $val;
} else if ($fieldCounts == 2) {
$f0 = $fields[0];
$fv0 = $val[$f0];
$f1 = $fields[1];
$fv1 = $val[$f1];
$parsedData[$fv0][$f1][] = $val;
} else {
exit("Third field not implemented");
}
}
Output
Array
(
[159] => Array
(
[subID] => Array <----------- SubID is fixed in your can cause confict
(
[0] => Array
(
[ID] => 159
[subID] => sub589
)
)
)
[334] => Array
(
[subID] => Array
(
[0] => Array
(
[ID] => 334
[subID] => sub703
)
)
)
)
A better Alternative to yours
$parsedData = array();
foreach ( $data as $val ) {
$temp = &$parsedData;
foreach ( array_slice($val, 0, $fieldCounts) as $key ) {
$temp = &$temp[$key];
}
$temp[] = $val;
}
print_r($parsedData);
Output
Array
(
[159] => Array
(
[sub589] => Array <---------- Make Sub ID Dynamic
(
[0] => Array
(
[ID] => 159
[subID] => sub589
)
)
)
[334] => Array
(
[sub703] => Array
(
[0] => Array
(
[ID] => 334
[subID] => sub703
)
)
)
)
Recommended Version For easy array path
$parsedData = array();
foreach ( $data as $val ) {
$temp = &$parsedData;
foreach ( array_slice($val, 0, $fieldCounts) as $key ) {
$temp = &$temp[$key];
}
$temp = $val;
}
print_r($parsedData);
Output
Array
(
[159] => Array
(
[sub589] => Array <---- Easy to asses as $parsedData['159']['sub589']
(
[ID] => 159
[subID] => sub589
)
)
[334] => Array
(
[sub703] => Array
(
[ID] => 334
[subID] => sub703
)
)
)
Instead of doing if/elseif/else inside your $data foreach-loop (which is always limited to the number you "write" in there with that structure and a lot of code-duplicateion) you need to turn that if/elseif/else into a loop of it's own.
But first of all transform the existing code, I start in the first if body, it contains already all code necessary:
$f0 = $fields[0];
$fv0 = $val[$f0];
$parsedData[$fv0][] = $val;
The $val should be assigned to the array $parsedData which is keyed by $fields name $value. Let's compress this here, the number 0 in names is superfluous as we don't want it any longer (but maybe the first):
$field = $fields[0];
$value = $values[$field];
$parsedData[$value][] = $values;
(I changed $val into $values to improve naming). This is now more easy to read and understand. Also we spot the magic number 0 here more easily.
Now to the magic. We want to add to an array here (push):
$parsedData[$value][] = $values;
To make this more easy, let's turn it this way:
$array = &$parsedData[$value];
$array[] = $values;
This right now seems superfluous, but when this turns into a loop, it will become more clear:
$array = &$parsedData;
...
$array = &array[$value];
...
$array[] = $values;
Let's review the code in with the outer loop at this moment:
foreach ($data as $values)
{
$array = &$parsedData;
$field = $fields[0];
$value = $values[$field];
$array = &$array[$value];
$array[] = $values;
}
Obviously this code is yet not complete. The inner-loop is missing but it starts to get some kind of body. And actually the inner loop is pretty simple to achieve:
$array = &$parsedData;
foreach ($fields as $field)
{
$value = $values[$field];
$array = &$array[$value];
}
$array[] = $values;
And that's already it. The single field has been turned into an iteration over all fields. The aliasing/referencing of the sub-array per each step in the iteration allows to push the value to the appropriate array entry after the inner loop has finished.
The whole outer and inner loop:
foreach ($data as $values)
{
$array = &$parsedData; # set reference
foreach ($fields as $field)
{
$value = $values[$field];
$array = &$array[$value];
}
$array[] = $values;
unset($array); # remove reference
}

I'm trying to sort a PHP Array, but can't figure out how

How do you convert an array in PHP that looks like this:
Array (
[2] => B.eot
[3] => B.ttf
[4] => CarnevaleeFreakshow.ttf
[5] => CarnevaleeFreakshow.eot
[6] => TRASHED.ttf
[7] => sub.ttf
)
To look like this:
Array(
[B]=>array(
[0] => B.eot
[1] => B.ttf
)
[CarnevaleeFreakshow]=>array(
[0] => CarnevaleeFreakshow.ttf
[1] => CarnevaleeFreakshow.eot
)
[TRASHED]=>array(
[0] => TRASHED.ttf
)
[sub]=>array(
[0] => sub.ttf
)
)
Is there a name for doing something like this?
the data is being retrieved from a
scandir
array.
<?php
$data = array (
2 => 'B.eot',
3 => 'B.ttf',
4 => 'CarnevaleeFreakshow.ttf',
5 => 'CarnevaleeFreakshow.eot',
6 => 'TRASHED.ttf',
7 => 'sub.ttf'
);
$new_data = array();
foreach ( $data as $value ) {
$tmp = explode( '.', $value );
$ext = '';
if ( $tmp[1] ) $ext = '.' . $tmp[1];
$new_data[ $tmp[0] ][] = $tmp[0] . $ext;
}
print_r( $new_data );
?>
Here is an example.
It can be written shorter, but I think this is the most instructive.
$ARRraw = array (
"B.eot",
"B.ttf",
"CarnevaleeFreakshow.ttf",
"CarnevaleeFreakshow.eot",
"TRASHED.ttf",
"sub.ttf"
) ;
$sorted = array();
foreach($ARRraw as $one){
$firstPoint = strpos($one,".");
// No point? then skip.
if (!($firstPoint === false)){
// Get the part before the point.
$myKey = substr($one,0,$firstPoint);
$sorted[$myKey][] = $one;
}
}
Is there a name for doing something like this?
Nope. Anyway, it should be rather simple using a loop:
<?php
$newArray = array( );
foreach( $originalArray as $fontfile ) {
$newArray[basename( $font )][] = $fontfile;
}
echo '<pre>' . print_r( $newArray, true );
To what i know there is no 'simple' method of doing this.
you could build a function to handle it though.
function convertArray($array) {
$newArray = array();
foreach( $array as $item ) {
$newArray[basename($item)] = $item;
}
return $newArray;
}
That should do what your looking for.
Try it:
function subdiv(array $arr) {
$res = array();
foreach($arr as $val) {
$tmp = explode('.', $val);
if(!isset($res[$tmp[0]]))
$res[$tmp[0]] = array();
$res[$tmp[0]][] = $val;
} return $res;
}
use with:
$res = subdiv($array);
var_dump($res);

PHP to find specific thing in an array

This is my array
Array (
[0] => "8266_hal_url"
[1] => "8266_hal_picture"
[2] => "8266_hal_status"
[3] => "8266_hal_qwert"
[4] => "4224423_hal_status"
[5] => "4223_hal_status"
)
How do I find all hal_status in an array and pass it to a query?
PHP >= 5.3.0
$testData = array ( '8266_hal_url',
'8266_hal_picture',
'8266_hal_status',
'8266_hal_qwert',
'4224423_hal_status',
'4223_hal_status',
);
$testNeedle = 'hal_status';
$result = array_filter($testData, function($arrayEntry) use ($testNeedle) {
return (strpos($arrayEntry,$testNeedle) !== false);
});
var_dump($result);
$result=array();
foreach ($myarray as $element)
if (strpos($element,'hal_status')===false) continue;
else $result[]=$element;
print_r($result);
Try this:
$result = array();
foreach($array as $item)
{
if(strpos($item, 'hal_status') !== false)
{
$result[] = $item;
}
}
print_r($result);

Categories