PHP array - explode some comma separated elements into new items - php

How can I take an array with individual strings but also comma separated strings and explode the comma separated items into individual items? For instance:
while(($row = mysql_fetch_array($downloads_query))) {
$product_array[] = $row['product'];
}
$product_array[] returns:
item 1: "10003"
item 2: "10016"
item 3: "10008, 10007, 10010"
How can I split item 3 into individual items 3, 4 and 5 so that $product_array returns:
item 1: "10003"
item 2: "10016"
item 3: "10008"
item 4: "10007"
item 5: "10010"

explode() - PHP.net:
Explodes a string based on the given delimiter, result is an array. Worth mentioning: if there's not a single delimiter inside your string, it will still convert to an array like Array ( [0] => abc ). This means you don't even need to cast your items 1 and 2 to an array in order to allow array_merge() to function correctly.
array_merge() - PHP.net:
Merges multiple arrays into a new array.
$items = new array();
while(($row = mysql_fetch_array($downloads_query))) {
$items = array_merge($items, explode(',', $item3));
}

while(($row = mysql_fetch_array($downloads_query))) {
if(strpos($row['product'],',') > -1){
$product_array += explode(',',$row['product']);
} else {
$product_array[] = $row['product'];
}
}
Here is fast solution :) if there is comma it will explode it before adding it into your array.
As other people notice myslq_ functions are deprecated .. Better use mysqli or PDO instead :)

You can try like this:
while(($row = mysql_fetch_array($downloads_query))) {
if(strstr($row['product'], ',')) {
$product_array = array_merge(explode(',',$row['product']), $product_array);
} else {
$product_array[] = $row['product'];
}
}

You can user explode() function in php and the merge the return array into $product_array. somthing like this:
$product_array = array_merge(explode(',', $commaSeperatedArray), $product_array);

The professional advice is to not do what you are doing. You should not be storing comma-separated values in table columns. These should be in their own table and JOINed when needed.
Anyhow, you can unconditionally explode and push the generated array into the perpetually flat result array using the spread operator (...).
Code: (Demo)
$array = [
"10003",
"10016",
"10008, 10007, 10010",
];
$result = [];
foreach ($downloads_query as $row) {
array_push($result, ...explode(', ', $row['product']));
}
var_export($result);
Output:
array (
0 => '10003',
1 => '10016',
2 => '10008',
3 => '10007',
4 => '10010',
)
Alternatively, just join the strings with the same delimiting substring as the delimited values, then explode on that same delimiter. (Demo)
var_export(
explode(', ', implode(', ', $array))
);

Untested, but here it goes.
function process_array($row)
{
$result=array();
$product=$row['product'];
if(strpos($product, ',')!==false)
{
$result[]=explode(',', $product);
}
else
{
$result[]=$product;
}
return $result;
}
/////
$product_array=array();
while(($row = mysql_fetch_array($downloads_query)))
{
$product_array=array_merge($product_array, proccess_array($row))
}
You get the idea...

Make use of preg_split() instead of explode().
You can add any number of delimiters you want inside the function.
<?php
while(($row = mysql_fetch_array($downloads_query))) {
$string .= $row['product']." ";
}
$product_array = preg_split( "/[;, ]/", $string);
?>

$format_Arr = array("test1","test2,test2.1","test3","test4,test5,test6,test7");
$formated_arr = array();
foreach($format_Arr as $arr){
$arr1 = explode(",",$arr);
if(count($arr1)>1){
$formated_arr = array_merge($formated_arr,explode(',',$arr));
}else{
$formated_arr[]= $arr;
}
}
print_r($formated_arr);

Related

Split, flatten, and remove duplicate values from result set containing comma-separated strings

A minimal sample array to represent the relevant portion of my query's result set:
[
['keyw' => 'sam , ram,shyam'],
['keyw' => 'sam,ram,shyam, mohan'],
['keyw' => 'sam, ram, shyam ,mohan,salman,babu , karan'],
]
I want to remove duplicate names to get an output like
[
sam,
ram,
shyam,
mohan,
salman,
babu,
karan
]
How can I achieve this?
<?php
include 'config.php';
$db = new Database();
$db->select('post','*',null,null,'id',20);
$result = $db->getResult();
if (count($result) > 0) {
foreach ($result as $row) {
$string = $row['keyw'];
$string = $string;
$array = explode(',', $string);
print_r(array_merge($array));
}
}
?>
You can use array_unique function for removing duplicate array values.
Like $arrayWithUniqueValues = array_unique($OriginalArray);
Because these seem like separate arrays, you can merge these first with array_merge, like: array_merge($array1, $array2).
The new array should only contain unique values then.
<?php
include 'config.php';
$db = new Database();
$db->select('post','*',null,null,'id',20); $result = $db->getResult(); if(count($result) > 0){
$newArray = array();
foreach ($result as $value) {
$sh_genres = $value['keyw'];
$sh_genres_array = array_map('trim', explode(',',$sh_genres));
$newArray = array_merge($newArray , $sh_genres_array );
}
$newUniqueArray = array_unique($newArray);
foreach($newUniqueArray as $links) {
echo '<p>'.$links.'</p>';
}}?>
You can split your column values on commas and consume the potential leading and trailing spaces around commas with preg_split(), then flip the values when pushing data into the result array to ensure uniqueness. Then when you want access the unique values, you can use array_keys() to convert the keys to values.
Code: (Demo)
$unique = [];
foreach ($db->getResult() as $row) {
$unique += array_flip(preg_split(
'/ *, */',
$row['keyw'],
0,
PREG_SPLIT_NO_EMPTY
));
}
var_export(array_keys($unique));

Parse formatted strings containing 3 delimiters to create multiple flat arrays

I have strings in following format:
$strings[1] = cat:others;id:4,9,13
$strings[2] = id:4,9,13;cat:electric-products
$strings[3] = id:4,9,13;cat:foods;
$strings[4] = cat:drinks,foods;
where cat means category and id is identity number of a product.
I want to split these strings and convert into arrays $cats = array('others'); and $ids = array('4','9','13');
I know that it can be done by foreach and explode function through multiple steps. I think I am somewhere near, but the following code does not work.
Also, I wonder if it can be done by preg_match or preg_split in fewer steps. Or any other simpler method.
foreach ($strings as $key=>$string) {
$temps = explode(';', $string);
foreach($temps as $temp) {
$tempnest = explode(':', $temp);
$array[$tempnest[0]] .= explode(',', $tempnest[1]);
}
}
My desired result should be:
$cats = ['others', 'electric-products', 'foods', 'drinks';
and
$ids = ['4','9','13'];
One option could be doing a string compare for the first item after explode for cat and id to set the values to the right array.
$strings = ["cat:others;id:4,9,13", "id:4,9,13;cat:electric-products", "id:4,9,13;cat:foods", "cat:drinks,foods"];
foreach ($strings as $key=>$string) {
$temps = explode(';', $string);
$cats = [];
$ids = [];
foreach ($temps as $temp) {
$tempnest = explode(':', $temp);
if ($tempnest[0] === "cat") {
$cats = explode(',', $tempnest[1]);
}
if ($tempnest[0] === "id") {
$ids = explode(',', $tempnest[1]);
}
}
print_r($cats);
print_r($ids);
}
Php demo
Output for the first item would for example look like
Array
(
[0] => others
)
Array
(
[0] => 4
[1] => 9
[2] => 13
)
If you want to aggregate all the values in 2 arrays, you can array_merge the results, and at the end get the unique values using array_unique.
$strings = ["cat:others;id:4,9,13", "id:4,9,13;cat:electric-products", "id:4,9,13;cat:foods", "cat:drinks,foods"];
$cats = [];
$ids = [];
foreach ($strings as $key=>$string) {
$temps = explode(';', $string);
foreach ($temps as $temp) {
$tempnest = explode(':', $temp);
if ($tempnest[0] === "cat") {
$cats = array_merge(explode(',', $tempnest[1]), $cats);
}
if ($tempnest[0] === "id") {
$ids = array_merge(explode(',', $tempnest[1]), $ids);
}
}
}
print_r(array_unique($cats));
print_r(array_unique($ids));
Output
Array
(
[0] => drinks
[1] => foods
[3] => electric-products
[4] => others
)
Array
(
[0] => 4
[1] => 9
[2] => 13
)
Php demo
I don't generally recommend using variable variables, but you are looking for a sleek snippet which uses regex to avoid multiple explode() calls.
Here is a script that will use no explode() calls and no nested foreach() loops.
You can see how the \G ("continue" metacharacter) allows continuous matches relative the "bucket" label (id or cat) by calling var_export($matches);.
If this were my own code, I'd probably not create separate variables, but a single array containing id and cat --- this would alleviate the need for variable variables.
By using the encountered value as the key for the element to be added to the bucket, you are assured to have no duplicate values in any bucket -- just call array_values() if you want to re-index the bucket elements.
Code: (Demo) (Regex101)
$count = preg_match_all(
'/(?:^|;)(id|cat):|\G(?!^),?([^,;]+)/',
implode(';', $strings),
$matches,
PREG_UNMATCHED_AS_NULL
);
$cat = [];
$id = [];
for ($i = 0; $i < $count; ++$i) {
if ($matches[1][$i] !== null) {
$arrayName = $matches[1][$i];
} else {
${$arrayName}[$matches[2][$i]] = $matches[2][$i];
}
}
var_export(array_values($id));
echo "\n---\n";
var_export(array_values($cat));
All that said, I probably wouldn't rely on regex because it isn't very readable to the novice regex developer. The required logic is much simpler and easier to maintain with nested loops and explosions. Here is my adjustment of your code.
Code: (Demo)
$result = ['id' => [], 'cat' => []];
foreach ($strings as $string) {
foreach (explode(';', $string) as $segment) {
[$key, $values] = explode(':', $segment, 2);
array_push($result[$key], ...explode(',', $values));
}
}
var_export(array_unique($result['id']));
echo "\n---\n";
var_export(array_unique($result['cat']));
P.s. your posted coding attempt was using a combined operator .= (assignment & concatenation) instead of the more appropriate combined operator += (assignment & array union).

Replace array value with more than one values

I have an array like this,
$array = array(
1,2,3,'4>12','13.1','13.2','14>30'
);
I want to find any value with an ">" and replace it with a range().
The result I want is,
array(
1,2,3,4,5,6,7,8,9,10,11,12, '13.1', '13.2', 14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30
);
My understanding:
if any element of $array has '>' in it,
$separate = explode(">", $that_element);
$range_array = range($separate[0], $separate[1]); //makes an array of 4 to 12.
Now somehow replace '4>12' of with $range_array and get a result like above example.
May be I can find which element has '>' in it using foreach() and rebuild $array again using array_push() and multi level foreach. Looking for a more elegant solution.
You can even do it in a one-liner like this:
$array = array(1,2,3,'4>12','13.1','13.2','14>30');
print_r(array_reduce(
$array,
function($a,$c){return array_merge($a,#range(...array_slice(explode(">","$c>$c"),0,2)));},
[]
));
I avoid any if clause by using range() on the array_slice() array I get from exploding "$c>$c" (this will always at least give me a two-element array).
You can find a little demo here: https://rextester.com/DXPTD44420
Edit:
OK, if the array can also contain non-numeric values the strategy needs to be modified: Now I will check for the existence of the separator sign > and will then either merge some cells created by a range() call or simply put the non-numeric element into an array and merge that with the original array:
$array = array(1,2,3,'4>12','13.1','64+2','14>30');
print_r(array_reduce(
$array,
function($a,$c){return array_merge($a,strpos($c,'>')>0?range(...explode(">",$c)):[$c]);},
[]
));
See the updated demo here: https://rextester.com/BWBYF59990
It's easy to create an empty array and fill it while loop a source
$array = array(
1,2,3,'4>12','13.1','13.2','14>30'
);
$res = [];
foreach($array as $x) {
$separate = explode(">", $x);
if(count($separate) !== 2) {
// No char '<' in the string or more than 1
$res[] = $x;
}
else {
$res = array_merge($res, range($separate[0], $separate[1]));
}
}
print_r($res);
range function will help you with this:
$array = array(
1,2,3,'4>12','13.1','13.2','14>30'
);
$newArray = [];
foreach ($array as $item) {
if (strpos($item, '>') !== false) {
$newArray = array_merge($newArray, range(...explode('>', $item)));
} else {
$newArray[] = $item;
}
}
print_r($newArray);

How to "write" with the strings of an array a text?

So my question might not be the best, so sorry for that.
I have an array with strings and want to write a text with the help of another array using it as the order/key. This is the Input:
$words =["I","am","cool"];
$order =["2","0","1","0","1","2"];
//var_export($words);
// array (
// 0 => 'I',
// 1 => 'am',
// 2 => 'cool',
// )
I want to use $order as some sort of key to rearrange $words so I can get this Output:
"Cool I am I am cool"
Help is much appreciated, thank you :)
Use the values of $order as the keys for $words.
$words =["I","am","cool"];
$order =["2","0","1","0","1","2"];
$output = '';
foreach($order as $key) {
$output .= $words[$key] . ' ';
}
echo ucfirst(trim($output));
Demo: https://eval.in/780785
The empty($real_key) is to check if it is the first iteration. Also could be == 0.
I would recommend the use of array_map and join
There is no need for
side-effecting manual iteration using foreach
if statements or ternary (?:) expressions
variable reassignment
string concatenation using .
checking array lengths
Here we go
function map_indexes_to_words ($indexes, $words) {
$lookup = function ($i) use ($words) {
return $words[(int) $i];
};
return join(' ', array_map($lookup, $indexes));
}
$words = ["I","am","cool"];
$order = ["2","0","1","0","1","2"];
echo map_indexes_to_words($order, $words);
// 'cool I am I am cool'
Start with an empty array.
Then loop through the order array and add the word array part to the new string.
$my_string= array();
foreach ( $order as $index ) {
$index = int($index);
$my_string[] = ( isset($words[ $index]) ) ? $words[ $index ] : '' );
}
$my_string = implode(' ', $my_string);
echo my_string;
Iterate over order and use it's values as keys to words; Convert the following code to php it should be pretty simple...
foreach (string orderIndexString in order) {
int orderIndexInt = System.Convert.ToInt16(orderIndexString); // convert string to int
if(orderIndexInt < 0 || orderIndexInt >= words.Length)
continue;
print (words[orderIndexInt]); // either print or add it to another string
}

How to group numbers in an array in php

I have a loads of numbers in a string
$userlist = '12,17,46,35,32,66,43,64'; //the userlist can be as long as i want
$arr2 = explode(',', $userlist);
i dont now how to get them to output like the follow.
12,17
46,35
32,66
43,64
Thank You for taking the time to read.
You can use array_chunk to group two together again and then iterate over the groups and implode each again with the ,. Example (Demo):
$userPairings = array_chunk($arr2, 2);
foreach ($userPairings as &$pair)
{
$pair = implode(',', $pair);
}
unset($pair);
echo implode("\n\n", $userPairings);
Output:
12,17
46,35
32,66
43,64

Categories