Hierarchical Array Conversion to Flat Array [duplicate] - php
This question already has answers here:
Merge two flat indexed arrays of equal size so that values are pushed into the result in an alternating fashion
(2 answers)
Closed 10 months ago.
I've got an array
$array = array(
array(1,2,3),
array('bob','bill'),
array(4,5,6,7)
//can have between 0 and 5 "rows"
);
I want to convert to an array that looks like this...
[1,bob,4, 1, bob, 5, 1, bob, 6, 1, bob, 7, 1, bill, 4 .... 3, bill, 7]
I was trying to write a recursive function for this which looks like...
function GetValues($array, $rowIndex, $valIndex, $values)
{
if(!isset($array[$rowIndex]))
{
return $values;
}
if(!isset($array[$rowIndex][$valIndex]))
{
return GetValues($array,$rowIndex+1, 0, $values);
}
$values[] = $array[$rowIndex][$valIndex];
return GetValues($array,$rowIndex, $valIndex+1, $values);
}
which just ends up iterating the array normally (prints 1,2,3,bob,bill,4,5,6,7)
$array = array(
array(1,2,3),
array('bob','bill'),
array(4,5,6,7)
);
function combinations($arrays) {
$result[] = array();
foreach ($arrays as $key => $values) {
$tmp = array();
foreach ($result as $result_item) {
foreach ($values as $value) {
$tmp[] = array_merge($result_item, array($key => $value));
}
}
$result = $tmp;
}
return $result;
}
$combinations_array = combinations($array);
$flat_string = '';
$flat_array = array();
foreach($combinations_array as $value){
foreach($value as $v){
$flat_string.=$v.',';
$flat_array[]=$v;
}
}
echo rtrim($flat_string,',');
print_r($flat_array);
Out Put string:
1,bob,4,1,bob,5,1,bob,6,1,bob,7,1,bill,4,1,bill,5,1,bill,6,1,bill,7,2,bob,4,2,bob,5,2,bob,6,2,bob,7,2,bill,4,2,bill,5,2,bill,6,2,bill,7,3,bob,4,3,bob,5,3,bob,6,3,bob,7,3,bill,4,3,bill,5,3,bill,6,3,bill,7
Output array:
Array
(
[0] => 1
[1] => bob
[2] => 4
[3] => 1
[4] => bob
[5] => 5
[6] => 1
[7] => bob
[8] => 6
[9] => 1
[10] => bob
[11] => 7
[12] => 1
[13] => bill
[14] => 4
[15] => 1
[16] => bill
[17] => 5
[18] => 1
[19] => bill
[20] => 6
[21] => 1
[22] => bill
[23] => 7
[24] => 2
[25] => bob
[26] => 4
[27] => 2
[28] => bob
[29] => 5
[30] => 2
[31] => bob
[32] => 6
[33] => 2
[34] => bob
[35] => 7
[36] => 2
[37] => bill
[38] => 4
[39] => 2
[40] => bill
[41] => 5
[42] => 2
[43] => bill
[44] => 6
[45] => 2
[46] => bill
[47] => 7
[48] => 3
[49] => bob
[50] => 4
[51] => 3
[52] => bob
[53] => 5
[54] => 3
[55] => bob
[56] => 6
[57] => 3
[58] => bob
[59] => 7
[60] => 3
[61] => bill
[62] => 4
[63] => 3
[64] => bill
[65] => 5
[66] => 3
[67] => bill
[68] => 6
[69] => 3
[70] => bill
[71] => 7
)
A problem you will likely have is not knowing how big the original array is. You can write it recursively by destroying the array. In this example, I shift the first element off the original array. Then, with each recursive call, I shift off another element. I use a for loop to go through the values and return what I've built.
function flatten($array)
{
if(sizeof($array)==0) return null;
$first = array_shift($array);
$ret = array();
foreach($first as $value)
{
$ret[] = $value;
$sub = flatten($array);
if($sub != null)
$ret = array_merge($ret, $sub);
}
return $ret;
}
Related
Remove from array past dates
I have the following array with different mixed dates from different years Array ( [0] => 2016-05-18 [1] => 2016-06-18 [2] => 2016-08-13 [3] => 2016-09-03 [4] => 2016-10-08 [5] => 2016-08-06 [6] => 2016-09-30 [7] => 2016-09-10 [8] => 2016-07-09 [9] => 2016-06-13 [10] => 2016-06-15 [11] => 2016-07-30 [12] => 2016-08-27 [13] => 2016-07-02 [14] => 2016-11-01 [15] => 2016-09-18 [16] => 2016-11-06 [17] => 2016-11-07 [18] => 2017-06-17 [19] => 2017-06-22 [20] => 2017-06-21 [21] => 2017-10-01 [22] => 2017-07-08 [23] => 2017-05-27 [24] => 2017-06-06 [25] => 2017-09-09 [26] => 2017-04-16 [27] => 2017-09-16 [28] => 2017-07-29 [29] => 2017-08-05 [30] => 2017-09-03 [31] => 2017-06-24 [32] => 2017-08-26 [33] => 2017-07-22 [34] => 2018-05-28 [35] => 2018-06-09 [36] => 2017-10-16 [37] => 2017-10-28 [38] => 2017-10-08 [39] => 2017-11-04 [40] => 2018-06-20 [41] => 2018-08-05 [42] => 2018-09-03 [43] => 2018-06-16 [44] => 2018-03-31 [45] => 2019-05-25 [46] => 2021-05-25 [47] => 2021-05-26 [48] => 2021-05-27 ) I want to remove all dates earlier than 2021 so my new array will have only the dates belonging to the current year of 2021. How can I filter the new array so all dates before 2021 will disappear? Array ( [0] => 2021-05-25 [1] => 2021-05-26 [2] => 2021-05-27 )
You can create a function that loops through the array and check if the string stars with 2021 if not, delete the element. For php 8 you can use function: str_starts_with(string $haystack, string $needle): bool For example: foreach($array as $key => $val){ if(!str_starts_with('2021', $val)){ unset($array[$key]); } } For previous php versions you can use strpos Example: foreach($array as $key => $val){ if (!strpos($val, '2021') == 0) { unset($array[$key]); } }
You have hashtag array-filter and PHP has array_filter function: $dates = [ '2016-05-18', '2018-03-31', '2019-05-25', '2021-05-25', '2021-05-26', '2021-05-27', ]; function myFilter($dt) { $year = date('Y',strtotime($dt)); return $year > 2020; } print_r(array_values(array_filter($dates, 'myFilter')));
You can loop over each date and use the dateTime object to compare the times to see if the date has passed a set date like the begining of a year and if it hasn't then add it to the new array. See below code: <?php //array with mixed date data $dateArray = array("2021-01-01","2016-05-18","2017-09-03","2018-06-16","2019-05-25","2021-05-25","2021-05-26","2021-05-27"); //the day you want to have everyday after (in this case the start of 2021) $setDate = "2021-01-01"; //array where the dates greater than then the set date will be stored. $newTimesArray = array(); $setDateObj = new \DateTime($setDate); // moved outside of loop foreach ($dateArray as $date) { $given_date = new \DateTime($date); //convert string to a date time object if ($given_date >= $setDateObj) { //if the date is greater than or equal to "2021-01-01" add it to the new array $newTimesArray[]=$date; } } //print the results echo print_r($newTimesArray,true); ?>
Split array into a unspecific number of chuncks
I have a string that contains the given answers from a qiuz by a user. This string is saved on the db table and it has this form. ,P1,1,2,3,5,8,9,,P2,1,3,4,5,6,8,9,,P3,1,2,3,4,6,8,9,,P4,1,,P5a,b,,P5b,d,,P5c,a,,P5d,c,,P6,4,,P7,2,,P8a,hc,,P8b,df,,P8c,bg,,P8d,e,,P9,4,,P10,3,,P11,4,,P12,2,,P13,3,,P14,3,,P15a,acejg,,P15b,dfhib,,P16,1,3,,P17,2,,P18,1,,P19,3,,P20,3,5,6 Ater getting the string i explode it, and the form becomes like this. Array ( [0] => P1 [1] => 1 [2] => 2 [3] => 3 [4] => 5 [5] => 8 [6] => 9 [7] => P2 [8] => 1 [9] => 3 [10] => 4 [11] => 5 [12] => 6 [13] => 8 [14] => 9 [15] => P3 [16] => 1 [17] => 2 [18] => 3 [19] => 4 [20] => 6 [21] => 8 [22] => 9 [23] => P4 [24] => 1 [25] => P5a [26] => b [27] => P5b [28] => d [29] => P5c [30] => a [31] => P5d [32] => c [33] => P6 [34] => 4 [35] => P7 [36] => 2 [37] => P8a [38] => hc [39] => P8b [40] => df [41] => P8c [42] => bg [43] => P8d [44] => e [45] => P9 [46] => 4 [47] => P10 [48] => 3 [49] => P11 [50] => 4 [51] => P12 [52] => 2 [53] => P13 [54] => 3 [55] => P14 [56] => 3 [57] => P15a [58] => acejg [59] => P15b [60] => dfhib [61] => P16 [62] => 1 [63] => 3 [64] => P17 [65] => 2 [66] => P18 [67] => 1 [68] => P19 [69] => 3 [70] => P20 [71] => 3 [72] => 5 [73] => 6 ) each question starts with a "P". So question 1 will be "P1" question 2 "P2" and so on. Each given answer is between the "P" until next "P". So the answers given from the user for the question number 1 are " 1 | 2 | 3 | 5 | 8 | 9 ". I was trying to insert the values to another array with a foreach loop but i could not find any way to seperate the answers. My desire output is. Array ( [P1] => Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 5 [4] => 8 [5] => 9 ) [P2] => Array ( [0] => 3 [1] => 4 [2] => 5 [3] => 6 [4] => 8 [5] => 9 ) ) Please tell me if you have any suggestions.Thank you very much
assuming we ve everything inside $p $res= array(); foreach($p as $key => $value){ if(strpos($value, "P") !== false){ $currentP = $value; $res[$currentP] = array(); }elseif($value){ $res[$currentP][] = $value; } } WORKING PHP FIDDLE tested with v5 and v7
This seems to work : <?php $string = ',P1,1,2,3,5,8,9,,P2,1,3,4,5,6,8,9,,P3,1,2,3,4,6,8,9,,P4,1,,P5a,b,,P5b,d,,P5c,a,,P5d,c,,P6,4,,P7,2,,P8a,hc,,P8b,df,,P8c,bg,,P8d,e,,P9,4,,P10,3,,P11,4,,P12,2,,P13,3,,P14,3,,P15a,acejg,,P15b,dfhib,,P16,1,3,,P17,2,,P18,1,,P19,3,,P20,3,5,6'; $array = explode(',', $string); $return = array(); $index = ''; foreach ($array as $v) { if (trim($v) == '') // Skip empty values continue; if (substr($v, 0, 1) == 'P') { $index = $v; if (!isset($return[$index])) $return[$index] = array(); } else { $return[$index][] = $v; } } var_dump($return); ?>
this could be an approach <?php $string = ',,P1,1,2,3,5,8,9,,P2,1,3,4,5,6,8,9,,P3,1,2,3,4,6,8,9,,P4,1,,P5a,b,,P5b,d,,P5c,a,,P5d,c,,P6,4,,P7,2,,P8a,hc,,P8b,df,,P8c,bg,,P8d,e,,P9,4,,P10,3,,P11,4,,P12,2,,P13,3,,P14,3,,P15a,acejg,,P15b,dfhib,,P16,1,3,,P17,2,,P18,1,,P19,3,,P20,3,5,6'; $sepAns = explode(',,',$string); echo $sepAns[2]; ?> Note that I added a , at the beginning to maintain integrity of ',,'
$str = ',P1,1,2,3,5,8,9,,P2,1,3,4,5,6,8,9,,P3,1,2,3,4,6,8,9,,P4,1,,P5a,b,,P5b,d,,P5c,a,,P5d,c,,P6,4,,P7,2,,P8a,hc,,P8b,df,,P8c,bg,,P8d,e,,P9,4,,P10,3,,P11,4,,P12,2,,P13,3,,P14,3,,P15a,acejg,,P15b,dfhib,,P16,1,3,,P17,2,,P18,1,,P19,3,,P20,3,5,6'; $arr = explode( ',', $str ); $structuredArr = array(); foreach ( $arr AS $element ) { if ( ( strpos( $element, 'P' ) === FALSE ) === FALSE ) { $key = $element; $structuredArr[ $key ] = array(); } else { if ( isset( $key ) ) { if ( !empty( $element ) ) { $structuredArr[ $key ][] = $element; } } } }
Selecting only even numbers in php output [duplicate]
This question already has answers here: How to filter an array by a condition (9 answers) Closed 6 years ago. I am trying to select and display only the even number in a separate output from this below function toms($c,$first = 0,$second = 1) { $toms = [$first,$second]; for($i=1;$i<$c;$i++) { $toms[] = $toms[$i]+$toms[$i-1]; } return $toms; } echo "<pre>"; print_r(toms(33)); ?> currently this outputs array ( [0] => 0 [1] => 1 [2] => 1 [3] => 2 [4] => 3 [5] => 5 [6] => 8 [7] => 13 [8] => 21 [9] => 34 [10] => 55 [11] => 89 [12] => 144 [13] => 233 [14] => 377 [15] => 610 [16] => 987 [17] => 1597 [18] => 2584 [19] => 4181 [20] => 6765 [21] => 10946 [22] => 17711 [23] => 28657 [24] => 46368 [25] => 75025 [26] => 121393 [27] => 196418 [28] => 317811 [29] => 514229 [30] => 832040 [31] => 1346269 [32] => 2178309 [33] => 3524578 ) Anyone know how I can display only the even numbers returned, so I would want to have 2, 8, 34 and so on thank you
You can use array_filter print_r(array_filter(toms(33), function($number){ return $number % 2 == 0; })); Or if you want to filter out 0: print_r(array_filter(toms(33), function($number){ return $number != 0 && $number % 2 == 0; })); A bit more readable: $isEvenNumber = function($number) { return $number % 2 == 0; } $numbers = toms(33); $filtered_numbers = array_filter($numbers, $isEvenNumber); var_dump($filtered_numbers);
Array merge failed
maybe it's simple as it look, but it driving me crazy. Here's my array : $result = Array ( [0] => Array ( [0] => 4 [1] => 4 [2] => 4 [3] => 4 [4] => 4 [5] => 4 [6] => 4 [7] => 4 [8] => 4 [9] => 4 [10] => 40 ) [1] => Array ( [0] => 5 [1] => 4 [2] => 4 [3] => 4 [4] => 4 [5] => 4 [6] => 4 [7] => 4 [8] => 4 [9] => 4 [10] => 41 ) [2] => Array ( [0] => 5 [1] => 5 [2] => 5 [3] => 5 [4] => 5 [5] => 5 [6] => 5 [7] => 5 [8] => 5 [9] => 5 [10] => 50 ) ) this is what i want transformed into : after array_merge: $result = Array ( [0] => 4 [1] => 4 [2] => 4 [3] => 4 [4] => 4 [5] => 4 [6] => 4 [7] => 4 [8] => 4 [9] => 4 [10] => 40 [11] => 5 [12] => 4 [13] => 4 [14] => 4 [15] => 4 [16] => 4 [17] => 4 [18] => 4 [19] => 4 [20] => 4 [21] => 41 [22] => 5 [23] => 5 [24] => 5 [25] => 5 [26] => 5 [27] => 5 [28] => 5 [29] => 5 [30] => 5 [31] => 5 [32] => 50 ) this is the code : <?php $result = array(); ?> #foreach ($detail_ratings as $detail_rating) <?php $result[] = json_decode($detail_rating); ?> #endforeach <?php $result = array_merge($result[0],$result[1],$result[2]); ?> {{print_r($result)}} how do i make it automatically without manually using this code : $result = array_merge($result[0],$result[1],$result[2]); this is what i already did : foreach ($result as $key => $value) { $values[] = array_merge($value,$result[$key]); }
Use this $result=array(); foreach($values as $value) { $result = array_merge($result,$value); }
Maybe this can help :- function nameit(array $arr) { $newarr = array(); foreach($arr as $a => $b) { $newarr[] = $b; } return $newarr; }
Try this: $final_array = array_merge($array1,$array2);
how do you assign the inner array values to a variable in php
I have an associative array in php. the content of associative array looks like this: Array ( [0] => Array ( [0] => 3 [1] => 1 [2] => 0 [3] => 50074494 [4] => 25013372 [5] => 2 [6] => 474 [7] => 0 [8] => 0 [9] => 0 [10] => 0 [11] => 985 [12] => 34951 [13] => 18143 [14] => 4 [15] => 2 [16] => 94 [17] => 1 [18] => 1.26 [19] => 7.9 [20] => 2013-06-27 10:19:21 ) [1] => Array ( [0] => 5 [1] => 1 [2] => 0 [3] => 50078122 [4] => 25000164 [5] => 2 [6] => 463 [7] => 0 [8] => 0 [9] => 0 [10] => 0 [11] => 860 [12] => 28290 [13] => 16944 [14] => 4 [15] => 1 [16] => 94 [17] => 1 [18] => 1.13 [19] => 7.1 [20] => 2013-06-27 10:19:51 ) [2] => Array ( [0] => 4 [1] => 1 [2] => 0 [3] => 50078630 [4] => 24995538 [5] => 2 [6] => 155 [7] => 0 [8] => 0 [9] => 0 [10] => 0 [11] => 616 [12] => 23203 [13] => 4892 [14] => 3 [15] => 1 [16] => 95 [17] => 0 [18] => 1.04 [19] => 6.5 [20] => 2013-06-27 10:20:21 ) ) I would like to be able to assign the inner array values to a variable. I need variable to look like this: echo $variable 3 1 0 50074494 25013372 2 474 .. 2013-06-27 10:19:21 . . I have this code so far: $variable; foreach ($lines as $key => $value) { foreach ($value as &$val) { $variable=$variable . $val . ' '; } echo $variable; echo "\n"; } with this code it looks like I am getting 3 times of variable. Any ideas what I am doing wrong here?
If you have an array, and you want to store the values in a space-separated string, you could do this: $string = implode(' ', $array); echo $string; So your loop might look like this: foreach ($lines as $value) { $value[20] = '"'. $value[20] .'"'; // from comments echo implode(' ', $value) ."\n"; }
I would recommend the use of implode instead of foreach. Also, it doesn't seem like you need the value of $key: foreach ($lines as $value) { echo implode(" ", $value); echo "\n"; } Also, I'm not sure I quite understood your question? What do you mean by "3 times of variable"?