I have three arrays right now the values of which I want to combine together. All of the values have matching keys but I can't work out quite how to do it. To put it more visually I have:
array{
[0] => "Foo"
}
array{
[0] => " Bar"
}
and I want:
array{
[0] => "Foo Bar"
}
But for the life of me I can't figure out how! At first I thought about using nested foreach statements like
$result = array();
foreach ($array1 as &$input1) {
foreach ($array2 as &$input2) {
$result[] = $input1 . $input2;
}
}
But while that combined the values, it generated a lot of correct ones (The array was about twice the size as expected).
Use the keys
$output = array();
foreach (array_keys($array1) as $key) {
$output[] = $array1[$key] . $array2[$key]; // and possibly . $array3[$key]
}
Related
I would like to combine these two foreach statements together. I've seen a few solutions around here, but nothing really works for me.
This is my username list from database.
$digits = [1,2,3,4];
$results = $db->table($usernames)
->where('memberID', $mID)->limit(10)
->getAll();
foreach ($results as $result) {
echo $result->userName;
}
I tried this:
$combined = array_merge($digits, $results);
foreach (array_unique($dogrularVeSiklar) as $single) : { ?>
{
echo $single.'<br>';
echo $results->userName;
},
}
You don't show what $dogrularVeSiklar is or where you get it, but as an example; combine into $key => $value pairs and foreach exposing the key and value:
$combined = array_combine($digits, $results);
foreach ($combined as $digit => $result) {
echo $digit . '<br>' . $result;
}
foreach operates on only one array at a time.
The way your array is structured, you can use array_combine() function to combine them into an array of key-value pairs then foreach that single array
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
im trying to mix my multi dimension arrays, and it iterates fine, but the output isnt what im trying to accomplish, i need to mix the values.
array= [ [ p ,t ,j ] , [ 9 , 3 , 6 ] ];
foreach($array as $value) {
foreach($value as $key => $val) {
echo $val;
}
}
}
array output: p,9,t,3,j,6 //should be
Mine is: p,t,j,9,3,6
Simplest approach
foreach($array[0] as $key => $value) {
echo $value, $array[1][$key];
}
if i understand you this is your answer:
//creat an empty array to save the new result
$result= array();
//do this for incrementing
$i=0;
//your arrays here and looping it
$array=array(array( p ,t ,j ) , array( 9 , 3 , 6 ) );
foreach($array as $a){
if(is_array($a)){
foreach($a as $b){
$result[$i]= $b;
}//end foreach
}else{
$result[$i]= $a;
}//end else
$i++;
}//end foreach
//then print_r to show your array
print_r($result);
have a nice day ^_^
by 'mix' do you mean trying to combine the secondary arrays into one long array? If that is the case:
$finalArray = array();
foreach($array as $value) {
$finalArray = array_merge($finalArray, $value);
}
edit: now that I look at it, I didn't quite echo the output like you needed, but the output should be in the correct order in the $finalArray and this should work with any amount of inner arrays.
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..
So far, if I have to loop through a multidimensional array, I use a foreach loop for each dimension.
e.g for two dimensions
foreach($array as $key=>$value)
{
foreach($value as $k2=>$v2)
{
echo
}
}
What do I do when I don't know the depth of the array? ie the depth is variable.
The only thing I can think of is to code a whole stack of loops and to break the loop if the next value is not an array.This seems a little silly.
Is there a better way?
Yes, you can use recursion. Here's an example where you output all the elements in an array:
function printAll($a) {
if (!is_array($a)) {
echo $a, ' ';
return;
}
foreach($a as $v) {
printAll($v);
}
}
$array = array('hello',
array('world',
'!',
array('whats'),
'up'),
array('?'));
printAll($array);
What you should always remember when doing recursion is that you need a base case where you won't go any deeper.
I like to check for the base case before continuing the function. That's a common idiom, but is not strictly necessary. You can just as well check in the foreach loop if you should output or do a recursive call, but I often find the code to be harder to maintain that way.
The "distance" between your current input and the base case is called a variant and is an integer. The variant should be strictly decreasing in every recursive call. The variant in the previous example is the depth of $a. If you don't think about the variant you risk ending up with infinite recursions and eventually the script will die due to a stack overflow. It's not uncommon to document exactly what the variant is in a comment before recursive functions.
You can do the below function for loop-through-a-multidimensional-array-without-knowing-its-depth
// recursive function loop through the dimensional array
function loop($array){
//loop each row of array
foreach($array as $key => $value)
{
//if the value is array, it will do the recursive
if(is_array($value) ) $array[$key] = loop($array[$key]);
if(!is_array($value))
{
// you can do your algorithm here
// example:
$array[$key] = (string) $value; // cast value to string data type
}
}
return $array;
}
by using above function, it will go through each of the multi dimensional array, below is the sample array you could pass to loop function :
//array sample to pass to loop() function
$data = [
'invoice' => [
'bill_information' => [
'price' => 200.00,
'quantity' => 5
],
'price_per_quantity' => 50.00
],
'user_id' => 20
];
// then you can pass it like this :
$result = loop($data);
var_dump($result);
//it will convert all the value to string for this example purpose
You can use recursion for this problem:
Here is one example
$array = array(1 => array(1 => "a", 2 => array(1 => "b", 2 => "c", 3 => array(1 => "final value"))));
//print_r($array);
printAllValues($array);
function printAllValues($arr) {
if(!is_array($arr)) {
echo '<br />' . $arr;
return;
}
foreach($arr as $k => $v) {
printAllValues($v);
}
}
It will use recursion to loop through array
It will print like
a
b
c
final value
Simple function inside array_walk_recursive to show the level of nesting and the keys and values:
array_walk_recursive($array, function($v, $k) {
static $l = 0;
echo "Level " . $l++ . ": $k => $v\n";
});
Another one showing use with a reference to get a result:
array_walk_recursive($array, function($v) use(&$result) {
$result[] = $v;
});
Based on previous recursion examples, here is a function that keeps an array of the path of keys a value is under, in case you need to know how you got there:
function recurse($a,$keys=array())
{
if (!is_array($a))
{
echo implode("-", $keys)." => $a <br>";
return;
}
foreach($a as $k=>$v)
{
$newkeys = array_merge($keys,array($k));
recurse($v,$newkeys);
}
}
recurse($array);