explode string to a multi array with 2 delimiter - php

I have this kind of sting i variable in php:
$hccRol = GA#COR,OP#COR,FOR#TB,GA#LTS,FOR#MOD,GA#PMAI,LDR#LID,HCC#LAD,HN#LAD,OP#LAD,GA#LAD,GA#WM,OP#WM,HN#WM,OP#VZ,HN#VZ,GA#VZAI
I want convert this to multi array that look somthing like this:
Array ( [GA] => Array ( [1] => COR
[2] => LTS
[3] => LAD
[4] => WM
[5] => VZAI
)
[FOR] => Array( [1] => TB
[2] => MOD
)
[OP] => Array( [1] => COR
[2] => WM
[3] => VZ
)
)
So the # determines in witch primary array the value must come

CBroe gave you the steps to do it the traditional way, so just for fun because I was bored:
parse_str(str_replace(array('#',','), array('[]=','&'), $hccRol ), $result);
print_r($result);
PHP >= 5.4.0:
parse_str(str_replace(['#',','], ['[]=','&'], $hccRol ), $result);

The following is a basic way to explode on the delimiting characters, iterate the data, and declare the new array structure. I will honor your desired output and start the keys at 1 instead of the standard 0.
Code: (Demo)
$hccRol = "GA#COR,OP#COR,FOR#TB,GA#LTS,FOR#MOD,GA#PMAI,LDR#LID,HCC#LAD,HN#LAD,OP#LAD,GA#LAD,GA#WM,OP#WM,HN#WM,OP#VZ,HN#VZ,GA#VZAI";
foreach (explode(",", $hccRol) as $item) {
$halves = explode("#", $item, 2);
if (!isset($result[$halves[0]])) {
$result[$halves[0]][] = null; // add zero key placeholder element
}
$result[$halves[0]][] = $halves[1];
unset($result[$halves[0]][0]); // remove the placeholder element
}
var_export($result);
Output:
array (
'GA' =>
array (
1 => 'COR',
2 => 'LTS',
3 => 'PMAI',
4 => 'LAD',
5 => 'WM',
6 => 'VZAI',
),
'OP' =>
array (
1 => 'COR',
2 => 'LAD',
3 => 'WM',
4 => 'VZ',
),
'FOR' =>
array (
1 => 'TB',
2 => 'MOD',
),
'LDR' =>
array (
1 => 'LID',
),
'HCC' =>
array (
1 => 'LAD',
),
'HN' =>
array (
1 => 'LAD',
2 => 'WM',
3 => 'VZ',
),
)
If you are happy to have the 0 indexes, then just remove the if{} block and the unset() line.

Related

Split strings in array to form three-element subarrays

I am practising with the AdventureWorks database for now and I will be receiving strings like the following: SalesOrderNumber=SOH123 and CustomerID=1. The strings may not always contain =, as they may be >, <, >=, <=, !=, <>.
Ideally, I would like to split each string into 3 fields - the database column to query, the comparison (e.g. =, >, !=, etc) and the value to search for.
I can achieve what I want with lots of code, comparing character by character, but I am hoping someone can suggest a really simple way to do this, as I am sure this must be a fairly common task for websites.
I don't want to just use the strings as they come through, as I need to sanitise them first. I also don't want to send bad queries to the database that may generate SQL errors.
It is indirect and feasibly inefficient to make calls of explode() within nested loops with break condition.
I recommend preg_split() as the right tool for the job. Create a capture group containing a character class of whitelisted symbols. Allow a maximum of 3 elements as its return value. Use the PREG_SPLIT_DELIM_CAPTURE flag to inform the function to preserve the delimiting comparison operators when exploding the string into three parts.
Code: (Demo)
var_export(
array_map(
fn($v) => preg_split(
'/([!<=>]+)/',
$v,
3,
PREG_SPLIT_DELIM_CAPTURE
),
$array
)
);
Output:
array (
0 =>
array (
0 => 'SalesOrderNumber',
1 => '=',
2 => 'SOH123',
),
1 =>
array (
0 => 'CustomerID',
1 => '=',
2 => '1',
),
2 =>
array (
0 => 'BigOrEqual',
1 => '>=',
2 => '44',
),
3 =>
array (
0 => 'SmallOrEqual',
1 => '<=',
2 => '67',
),
4 =>
array (
0 => 'NotEqual',
1 => '!=',
2 => '123',
),
5 =>
array (
0 => 'NotEqual',
1 => '<>',
2 => '2000',
),
6 =>
array (
0 => 'Smaller',
1 => '<',
2 => '21',
),
7 =>
array (
0 => 'Bigger',
1 => '>',
2 => '12',
),
)
This is my aproach using foreach, explode and array functions:
$strings = [
'SalesOrderNumber=SOH123',
'CustomerID=1',
'BigOrEqual>=44',
'SmallOrEqual<=67',
'NotEqual!=123',
'NotEqual<>2000',
'Smaller<21',
'Bigger>12',
];
function explodeOperators(array $strings) : array
{
$operators = ['>=','<=','!=','<>','<','>','=']; // do not change this order
$result = [];
foreach ($strings as $expression) {
$found = false;
foreach ($operators as $operator) {
$exploded = explode($operator, $expression);
if (count($exploded) > 1 and $found === false) {
$found = true;
array_splice($exploded, 1, 0, $operator);
$result[] = $exploded;
}
}
}
return $result;
}
$result = explodeOperators($strings);
print_r($result);
That will result:
Array
(
[0] => Array
(
[0] => SalesOrderNumber
[1] => =
[2] => SOH123
)
[1] => Array
(
[0] => CustomerID
[1] => =
[2] => 1
)
[2] => Array
(
[0] => BigOrEqual
[1] => >=
[2] => 44
)
[3] => Array
(
[0] => SmallOrEqual
[1] => <=
[2] => 67
)
[4] => Array
(
[0] => NotEqual
[1] => !=
[2] => 123
)
[5] => Array
(
[0] => NotEqual
[1] => <>
[2] => 2000
)
[6] => Array
(
[0] => Smaller
[1] => <
[2] => 21
)
[7] => Array
(
[0] => Bigger
[1] => >
[2] => 12
)
)

Move an element to first position in an array

here is my array:
Array
(
[0] => Array
(
[id] => 8
[title] => MUSIC
)
[1] => Array
(
[id] => 17
[title] => Indie
)
[2] => Array
(
[id] => 14
[title] => SPORTS
)
[3] => Array // Need to move this on first position
(
[id] => 15
[title] => Hipster
)
[4] => Array
(
[id] => 16
[title] => Web Seriesdf
)
)
I want array with key [3] to be on first position and then the rest of the elements.
I tried array_merge and array_unshift. But not working
You just need to take only three steps.
- Copy n'th array in variable.
- Delete n'th index from array. using unset()
- Put variable at the 0th index of the array. Using array_unshift()
Step 1:
$array=$mainArray[N];
Step 2:
unset($mainArray[N]);
Step 3:
array_unshift($mainArray, $array);
Lets assume your array to be $x;
$new_value = $x[3];
unset($x[3]);
array_unshift($x,$new_value);
This shall solve your problem.
You can also use array_merge
<?php
$a = [1,2,3,4,5];
$new_value = [$a[1]];
unset($a[1]);
$c = array_merge($new_value,$a);
print_r($c);
?>
Check output : https://eval.in/590702
Use
$array = array('3' => $array['3']) + $array;
phpfiddle Preview and eval.in Preview
Note: im moving 2 in my array. In your method add 3
Example
$array = array(
'0' => array(
'id'=>'8',
'title'=>'MUSIC'
),
'1' => array(
'id'=> '17',
'title'=> 'Indie'
),
'2' => array(
'id'=>'14',
'title'=>'SPORTS',
),
'3' => array(
'id'=>'14',
'title'=>'SPORTS',
),
);
$array = array('2' => $array['2']) + $array;
print_r($array);
Output
Array ( [2] => Array ( [id] => 14 [title] => SPORTS ) [0] => Array ( [id] => 8 [title] => MUSIC ) [1] => Array ( [id] => 17 [title] => Indie ) [3] => Array ( [id] => 14 [title] => SPORTS ) )
Use array_unshift();
Please check below code.
<?php
$a = Array(
'0' => Array('id' => '8','title' => 'MUSIC'),
'1' => Array('id' => '17','title' => 'Indie'),
'2' => Array('id' => '14','title' => 'SPORTS'),
'3' => Array('id' => '15','title' => 'Hipster'),
'4' => Array('id' => '16','title' => 'Web Seriesdf')
);
echo '<pre>';print_r($a);
$a3 = $a['3'];
unset($a['3']);
array_unshift($a,$a3);
echo '<pre>';print_r($a);
?>
Check output - https://eval.in/590723

add items to multidimensional array programmatically in php

I have the following array
$a = array(0 => 'Item',
1 => 'Wattles',
2 => 'Types',
3 => 'Compost',
4=> 'Estimated',
5 => '123',
6 => 'Actual',
7 => '12',
);
That is sorted with the following code.
echo "<pre>";
print_r($a);
$a_len = count($a);
$fnl = array();
$i = 0;
while($i<$a_len){
$fnl[$a[$i]] = $a[++$i];
$i++;
}
print_r($fnl);
It prints correctly
Array
(
[Item] => Wattles
[Types] => Compost
[Estimated Qty] => 123
[Actual Qty] => 12
)
until i add multiple entries.
Array
(
[0] => Item
[1] => Wattles
[2] => Types
[3] => Compost
[4] => Estimated Qty
[5] => 123
[6] => Actual Qty
[7] => 12
[8] => Item
[9] => Silt Fence
[10] => Types
[11] => Straw
[12] => Estimated Qty
[13] => 45
[14] => Actual Qty
[15] => 142
)
I need to make this add items in a multidimensional array.
$items = array
(
array("Wattles","Silt Fence), //items
array("Compost","Straw"), //types
array(123,45), //estimated quantity
array(12,142) //actual quantity
);
There are a few given numbers. There are exactly 4 entries (8 items) before the list repeats itself.
I have been stuck on this portion for hours, and don't know how to get my code working as I want it to.
To get the expected result with string keys you can do:
foreach(array_chunk($a, 2) as $pairs) {
$result[$pairs[0]][] = $pairs[1];
}
Yields:
Array
(
[Item] => Array
(
[0] => Wattles
[1] => Silt Fence
)
[Types] => Array
(
[0] => Compost
[1] => Straw
)
[Estimated] => Array
(
[0] => 123
[1] => 45
)
[Actual] => Array
(
[0] => 12
[1] => 142
)
)
Then if you want it numerically indexed:
$result = array_values($result);
You have your structure for a multidimensional array wrong. You should construct your array like this:
$a = array(
0 => array(
'Item' => 'Wattles',
'Types' => 'Compost',
'Estimated' => 123,
'Actual' => 12
)
);
Then to add to it:
$a[] = array(
'Item' => 'Silt Fence',
'Types' => 'Straw',
'Estimated' => 45,
'Actual' => 142
);
Render it out to see the results which are what I think you are looking for.
print_r($a);
I can post a link if you want to learn how to sort multidimensional arrays by sub-array values if you need.

array_slice in multidimensional array?

I have an array in php like this :
Array
(
[0] => Array
(
[915] => 1
[1295] => 1
[1090] => 1
[1315] => 0.93759357774
[128] => 0.93759357774
[88] => 0.731522789561
[1297] => 0.731522789561
[1269] => 0.525492880722
[1298] => 0.525492880722
[121] => 0.519133966069
)
[1] => Array
(
[585] => 1
[1145] => 1
[1209] => 1
[375] => 1
[1144] => 1
[913] => 1
[1130] => 0.996351158355
[215] => 0.937096401456
[1296] => 0.879373313559
[30] => 0.866473953643
[780] => 0.866473953643
[1305] => 0.866473953643
[1293] => 0.866473953643
)
)
How do I get the 1st-5th rows of sub-array for each array, like this :
Result :
Array
(
[0] => Array
(
[915] => 1
[1295] => 1
[1090] => 1
[1315] => 0.93759357774
[128] => 0.93759357774
)
[1] => Array
(
[585] => 1
[1145] => 1
[1209] => 1
[375] => 1
[1144] => 1
)
)
$multid_array = array(/* Your Multidimensional array from above*/);
$sliced_array = array(); //setup the array you want with the sliced values.
//loop though each sub array and slice off the first 5 to a new multidimensional array
foreach ($multid_array as $sub_array) {
$sliced_array[] = array_slice($sub_array, 0, 5);
}
The $sliced_array will then contain the output you wanted.
Iterate over the array.
Read the value by reference.
Delete key-values from offset 5 till
the end. You need not collect the return value because we are using the reference to the original array.
.
foreach($mainArray as $key => &$value) {
array_splice($value,5);
}
Working ideone link
You might want to look into the php function array_splice.
http://no.php.net/manual/en/function.array-slice.php

How to sort multiple arrays in PHP

i have wrote a script to produce an array of data but now want to display in order of score. The array outputs as follows;
[display_name] => Array
(
[0] => ACT_Web_Designs
[1] => user1_design
[2] => user2_design
)
[proffesion] => Array
(
[0] => Web Developer
[1] => web developer
[2] => Web Developer
)
[score] => Array
(
[0] => 15
[1] => 6
[2] => 15
)
[img] => Array
(
[0] => ./?0000=gif&0001=3fadb8c362ff39f3322909899ff14760&0002=prof_pic
[1] =>
[2] =>
)
so in a nutshell I am wanting it to be converted as follows;
[display_name] => Array
(
[0] => ACT_Web_Designs
[1] => user2_design
[2] => user1_design
)
[proffesion] => Array
(
[0] => Web Developer
[1] => web developer
[2] => Web Developer
)
[score] => Array
(
[0] => 15
[1] => 15
[2] => 6
)
[img] => Array
(
[0] => ./?0000=gif&0001=3fadb8c362ff39f3322909899ff14760&0002=prof_pic
[1] =>
[2] =>
)
I have been looking at asort() but cant get anything to work. any help would be much appreciated.
This is exactly where the PHP's array_multisort comes to use. It is a case where you want to sort many arrays based on the comparison happening in just one of them.
I've modified the array score to have distinct values.
<?php
$arr = array(
'display_name' => array('ACT_Web_Designs','user1_design','user2_design'),
'proffesion' => array('Web Developer','web developer','web developer'),
'score' => array(12,6,15),
'img' => array('./?0000=gif&0001=3fadb8c362ff39f3322909899ff14760&0002=prof_pic','','')
);
var_dump($arr);
array_multisort($arr['score'], SORT_ASC, SORT_NUMERIC,
$arr['display_name'],
$arr['proffesion'],
$arr['img']
);
var_dump($arr);
?>
Here goes a working demo.
How about this simpler one
$arr = array("k"=>array("A","B","C"),"l"=>array(15,6,15),"n"=>array("k","l","n"));
array_multisort($arr["k"],SORT_NUMERIC,SORT_DESC,$arr["l"],$arr["n"]);
var_dump($arr);
Doesn't it work to just rsort the score array?
rsort($data['score'], SORT_NUMERIC);
I have managed to do this, i was just after a more efficient way;
$array = array(
'display_name' => array(0 => 'ACT_Web_Designs', 1 => 'user1_design', 2 => 'user2_design' ),
'proffesion' => array( 0 => 'Web Developer', 1 => 'web developer', 2 => 'Web Developer' ),
'score' => array( 0 => 15, 1 => 6, 2 => 15 ),
'img' => array( 0 => './?0000=gif&0001=3fadb8c362ff39f3322909899ff14760&0002=prof_pic', 1 => '', 2 => '' )
);
arsort($array['score'], SORT_NUMERIC );
foreach($array['score'] as $key => $val ) {
$newarray['display_name'][] = $array['display_name'][$key];
$newarray['proffesion'][] = $array['proffesion'][$key];
$newarray['score'][] = $array['score'][$key];
$newarray['img'][] = $array['img'][$key];
}
print_r($newarray);
returns
Array
(
[display_name] => Array
(
[0] => ACT_Web_Designs
[1] => user2_design
[2] => user1_design
)
[proffesion] => Array
(
[0] => Web Developer
[1] => Web Developer
[2] => web developer
)
[score] => Array
(
[0] => 15
[1] => 15
[2] => 6
)
[img] => Array
(
[0] => ./?0000=gif&0001=3fadb8c362ff39f3322909899ff14760&0002=prof_pic
[1] =>
[2] =>
)
)
Use rsort()
<?php
$fruits = array("lemon", "orange", "banana", "apple");
rsort($fruits);
reset($fruits);
while (list($key, $val) = each($fruits)) {
echo "$key = $val\n";
}
?>
This example would display:
0 = orange
1 = lemon
2 = banana
3 = apple
The most elegant solution that I could find would not reorder the data structure but merely access it in a different fashion.
$scores = $data['score'];
arsort($scores);
$keys_ordered_by_score = array_keys($scores);
Now you can, say, grab the display_name and "proffesion" that has the highest score by the following:
$first_place = $keys_ordered_by_score[0];
echo $data['display_name'][$first_place],
' is a ', $data['proffesion'][$first_place];
Of course, if you really need to reorder the data structure, this idea is useless to you. Any of the other answers using array_multisort() will likely suit that need.
This will not re-sort them for you, but it will let you go through them in the order you want. You can reassign them if you want, but I'd just use this for the output order.
Edit: This will not work, due to the possibility of non-unique key values. See Comments below, and learn from my mistake
$sort_order = $array['score'];
arsort($sort_order);
$sort_order = array_flip($sort_order);
foreach($sort_order as $key){
echo $array['display_name'][$key].' - '.$array['score'][$key];
}

Categories