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"?

Categories