I have this variable $sid and its output is below.
$sid = $_POST['sid'];
// sid consists values like this.
Array
(
[0] => 1
[1] => 2,3
)
now I need to run a query with this sid 1, 2 and 3. To do that I am using following code:
$ex = array();
foreach ( $sid as $key => $value) {
$ex[] = explode(',', $value);
}
foreach ($ex as $key => $value) {
foreach ($value as $k => $v) {
echo $v;
// my query where sid = $v
}
}
Is there any better way without multiple foreach loop?
Try this:
$ex = explode(',', implode(',', $sid));
foreach ($ex as $v) {
echo $v;
}
Basically, your input is an array of strings of comma-separated values, so, you can merge these strings into single string with comma as separator, and then split whole thing using single explode call.
Related
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).
I have a little problem in my project : I would like display only the key of each array when I click on a element of my list. Dump of my table
For example when I click in "Paupiette", I would like display 0.
I partially succeeded but when I click in a element, I see only the last key (here "1").
Here,you can see the code
$carts = $cartService->getCart($user);
//dump($carts); die;
$mykey = 0;
foreach($carts as $key => $value) {
$mykey = $key;
}
dump($mykey);die;
If you have any idea, thank you a lot
You have multiple choice to display your $keys
the first one is :
$keys = array_keys($carts);
The second is :
foreach ($carts as $key => $value) {
dump($key);
}
if you will display all keys after loop
$myKeys = array();
foreach($carts as $key => $value) {
$myKeys[] = $key;
}
dump($myKeys);die;
If you just want to display the keys, following your coding "style":
foreach ($carts as $key => $value) {
dump($key);
}
If you want to display the keys as comma-separated string, again following your coding "style":
$keys = array_keys($carts); // Get the keys, eg, [0, 1];
$str = implode(', ', $keys); // Convert the array to string, eg, "0, 1"
dump($str);
I have a string that I converted to a multi-dimensional array.
String: 13,4,3|65,1,1|27,3,2
I wanna be able to move 27,3,2 to index 1 for example, so it would become:
13,4,3|27,3,2|65,1,1
Or remove one of those sections.
I know I can unset(), but I'm not sure how to search for an index then move it or unset it.
You can try the below one for interchanging the position of last two elements
$array = [0 => array(13,4,3), 1=>array(65,1,1), 2 => array(27,3,2)];
foreach($array as $key => $value) {
if($key == count($array)-1) {
$array[$key] = $array[$key-1];
$array[$key-1] = $value;
}
}
This is for removing the second element.
$array = [0 => array(13,4,3), 1=>array(65,1,1), 2 => array(27,3,2)];
foreach($array as $key => $value) {
if($key == count($array)-1) {
$array[$key-1] = $value;
unset($array[$key]);
}
}
Loop through the array using foreach
foreach($array as $key => $value)
From key you can get the key and can do whatever you like.
Other wise, you can do this if you know the key
echo $array['pass_key_name_here'];
I would post the entire code, but it is lengthly and confusing, so I'll keep it short and simple. This is complicated for myself, so any help will be greatly appreciated!
These are the values from my Array:
Light Blue1
Blue2
Blue1
Black3
Black2
Black1
The values I need to retrieve from my Array are "Light Blue1", "Blue2" and "Black3". These are the "highest values" for each color.
Something similar to what I'm looking for is array_unique, but that wouldn't work here. So something along those lines that can retrieve each color with its highest number.
Thanks!
Assuming your format is always NameNumber a regex should do the trick for separating the data. This will loop through your data in the order your provide and grab the first element that is different and put it into $vals. I am also assuming your data will always be ordered as your example shows
$data = ['Light Blue1',
'Blue2',
'Blue1',
'Black3',
'Black2',
'Black1'];
$vals = [];
$current = '';
foreach($data as $row) {
if(!preg_match('/(.*)(\d)/i', $row, $matched)) continue;
if($matched[1] != $current) {
$vals[] = $row;
$current = $matched[1];
}
}
The solution using preg_split and max functions:
$colors = ['Light Blue1', 'Blue2', 'Blue1', 'Black3', 'Black2', 'Black1'];
$unique_colors = $result = [];
foreach ($colors as $k => $v) {
$parts = preg_split("/(\d+)/", $v, 0, PREG_SPLIT_DELIM_CAPTURE);
$unique_colors[$parts[0]][] = (int) $parts[1];
}
foreach ($unique_colors as $k => $v) {
$result[] = $k . max($v);
}
print_r($result);
The output:
Array
(
[0] => Light Blue1
[1] => Blue2
[2] => Black3
)
If you pre-sort your array with "natural sorting", then you can loop through the array and unconditionally push values into the result with digitally-trimmed keys. This will effectively overwrite color entries with lesser number values and only store the the highest numbered color when the loop finishes.
Code: (Demo)
natsort($data);
$result = [];
foreach ($data as $value) {
$result[rtrim($value, '0..9')] = $value;
}
var_export(array_values($result));
Or you could parse each string and compare the number against its cached number (if encountered before): (Demo)
$result = [];
foreach ($data as $value) {
sscanf($value, '%[^0-9]%d', $color, $number);
if (!isset($result[$color]) || $result[$color]['number'] < $number) {
$result[$color] = ['value' => $value, 'number' => $number];
}
}
var_export(array_column($result, 'value'));
A related technique to find the highest value in a group
How can I get the list of values from my array:
[data] => Array
(
[5] => Array
(
[0] => 19
[1] => 18
[2] => 20
)
[6] => Array
(
[0] => 28
)
)
Expected output result string will be: 19,18,20,28
Thanks!
With one line, no loop.
echo implode(',', call_user_func_array('array_merge', $data));
Try it here.
Use following php code:
$temp = array();
foreach($data as $k=>$v){
if(is_array($v)){
foreach($v as $key=>$value){
$temp[] = $value;
}
}
}
echo implode(',',$temp);
Use following code.
$string = '';
foreach($yourarray as $k){
foreach($k as $l){
$string. = $l.",";
}
}
Just loop over sub arrays. Store values to $result array and then implode with ,
$result = array();
foreach ($data as $subArray) {
foreach ($subArray as $value) {
$result[] = $value;
}
}
echo implode(',', $result);
$data = array(5 => array(19,18,20), 6 => array(28));
foreach ($data as $array) {
foreach ($array as $array1) {
echo $array1.'<br>';
}
}
Try this one. It will help you
Since all of the data that you wish to target are "leaf nodes", array_walk_recursive() is a handy function to call.
Code: (Demo)
$data=[5=>[19,18,20],6=>[28]];
array_walk_recursive($data,function($v){static $first; echo $first.$v; $first=',';});
Output:
19,18,20,28
This method uses a static declaration to avoid the implode call and just iterates the call of echo with preceding commas after the first iteration. (no temporary array generated)
I haven't really taken the time to consider any fringe cases, but this is an unorthodox method that will directly provide the desired output string without loops or even generating a new, temporary array. It's a tidy little one-liner with a bit of regex magic. (Regex Demo) It effectively removes all square & curly brackets and double-quoted keys with trailing colons.
Code: (Demo)
$data=[5=>[19,18,20],6=>[28]];
echo preg_replace('/[{}[\]]+|"\d+":/','',json_encode($data));
Output:
19,18,20,28
To be clear/honest, this is a bit of hacky solution, but I think it is good for SO researchers to see that there are often multiple ways to achieve any given outcome.
try with this..
foreach($data as $dataArr){
foreach ($subArray as $value) {
$res[] = $value;
}
}
echo implode(',', $res);
Just use nested foreach Statements
$values = array();
foreach($dataArray as $key => $subDataArray) {
foreach($subDataArray as $value) {
$values[] = $value;
}
}
$valueString = implode(',', $values);
Edit: Added full solution..