This question already has answers here:
How to implode an array to new lines [duplicate]
(2 answers)
Closed 10 months ago.
I have this array:
array(1) {
["comments"]=>
array(244) {
[113]=>
array(2) {
[0]=>
string(40) "2016-07-15 09:27 | From On Track to Done"
[1]=>
string(40) "2016-07-15 09:56 | From Done to On Track"
}
}
}
And I want to make into this array:
array(1) {
["comments"]=>
array(244) {
[113]=>
array(1) {
[0]=>
string(80) "2016-07-15 09:27 | From On Track to Done
2016-07-15 09:56 | From Done to On Track"
}
}
}
I need to keep the key [113] and merge the values.
I need all the comments to be in only one array.
In this example there are only two comments, but actually it is much more.
I tried with array_merge, array_value and a loop. I couldnt get it.
A more general algorithm would be :
<?php
// SAMPLE DATA.
$arr = array( "comments" => array( 0 => array( "2016-07-15 09:27 | From On Track to Done",
"2016-07-15 09:56 | From Done to On Track"
),
1 => array( "111 | aaa",
"222 | bbb",
"333 | ccc"
)
),
"posts" => array( 0 => array( "2016-07-13 08:00 | bla bla bla",
"2016-07-13 08:30 | more bla bla bla"
),
1 => array( "444 | xxx",
"555 | yyy",
"666 | zzz"
)
)
);
var_dump( $arr ); // ORIGINAL ARRAY.
$new = array();
foreach ( $arr as $key => $category ) // "COMMENTS", "POSTS", ...
{ for ( $i = 0; $i < count( $category ); $i++ ) // 0, 1, ...
{ $values = implode( $category[ $i ]," " ); // MERGE STRINGS.
$new[ $key ][ $i ] = array( $values );//WE CAN REMOVE "ARRAY" AND LEAVE ONLY "$VALUES".
}
}
var_dump( $new ); // NEW ARRAY.
?>
Result :
original array
array (size=2)
'comments' =>
array (size=2)
0 =>
array (size=2)
0 => string '2016-07-15 09:27 | From On Track to Done' (length=40)
1 => string '2016-07-15 09:56 | From Done to On Track' (length=40)
1 =>
array (size=3)
0 => string '111 | aaa' (length=9)
1 => string '222 | bbb' (length=9)
2 => string '333 | ccc' (length=9)
'posts' =>
array (size=2)
0 =>
array (size=2)
0 => string '2016-07-13 08:00 | bla bla bla' (length=30)
1 => string '2016-07-13 08:30 | more bla bla bla' (length=35)
1 =>
array (size=3)
0 => string '444 | xxx' (length=9)
1 => string '555 | yyy' (length=9)
2 => string '666 | zzz' (length=9)
new array
array (size=2)
'comments' =>
array (size=2)
0 =>
array (size=1)
0 => string '2016-07-15 09:27 | From On Track to Done 2016-07-15 09:56 | From Done to On Track' (length=81)
1 =>
array (size=1)
0 => string '111 | aaa 222 | bbb 333 | ccc' (length=29)
'posts' =>
array (size=2)
0 =>
array (size=1)
0 => string '2016-07-13 08:00 | bla bla bla 2016-07-13 08:30 | more bla bla bla' (length=66)
1 =>
array (size=1)
0 => string '444 | xxx 555 | yyy 666 | zzz' (length=29)
Try this:
$array['comments'][113] = implode(' ', $array['comments'][113]);
I don't know what is your array structure, but simple solution is:
$vals = implode("\n", $ar['comments'][113]);
$ar['comments'][113] = array();
$ar['comments'][113][] = $vals;
Or simpler:
$ar['comments'][113] = array(implode("\n", $ar['comments'][113]));
Thank you for the help! You were right. It was with implode.
The answer was this:
foreach ($goals["comments"] as $key => $value) {
$goals['comments'][$key][0] = implode($value, "\n");
}
Related
I know the answer to this will be obvious but I have spent the last 3 days trying to figure it out. I am having trouble getting a Multi-Dimensional array to export into the correct layout in the exported .csv file.
I seem to able to either get all the data but not in the correct layout or I can get the correct layout but not all the data.
This is the array
array (size=106)
0 =>
array (size=6)
0 => string 'Title' (length=5)
1 => string 'image_url' (length=9)
3 => string 'SKU CODE' (length=8)
4 => string 'TITLE SIZE' (length=10)
5 => string 'DESCRIPTION' (length=11)
6 => string 'BASE SKU' (length=8)
1 =>
array (size=6)
0 => string 'A witch and her cat live here' (length=29)
1 => string 'https://beautifulhomegifts.com/a-witch-and-her-cat-live-here/' (length=61)
3 =>
array (size=4)
0 => string 'BHG-MS-AWAHCLH030720' (length=20)
1 => string 'BHG-MS-AWAHCLH030720-A5' (length=23)
2 => string 'BHG-MS-AWAHCLH030720-A4' (length=23)
3 => string 'BHG-MS-AWAHCLH030720-A3' (length=23)
4 =>
array (size=4)
0 => string 'A witch and her cat live here' (length=29)
1 => string 'A witch and her cat live here - 150mm x 200mm' (length=45)
2 => string 'A witch and her cat live here - 201mm x 305mm' (length=45)
3 => string 'A witch and her cat live here - 305mm x 400mm' (length=45)
5 =>
array (size=4)
0 => string 'A witch and her cat live here' (length=29)
1 => string 'A witch and her cat live here' (length=29)
2 => string 'A witch and her cat live here' (length=29)
3 => string 'A witch and her cat live here' (length=29)
6 =>
array (size=3)
1 => string 'BHG-MS-AWAHCLH030720' (length=20)
2 => string 'BHG-MS-AWAHCLH030720' (length=20)
3 => string 'BHG-MS-AWAHCLH030720' (length=20)
2 =>
array (size=2)
0 => string '' (length=0)
1 => string '' (length=0)
3 =>
array (size=2)
0 => string '' (length=0)
1 => string '' (length=0)
4 =>
array (size=2)
0 => string '' (length=0)
1 => string '' (length=0)
5 =>
array (size=6)
0 => string 'Autism House Rules' (length=18)
1 => string 'https://beautifulhomegifts.com/autism-house-rules/' (length=50)
3 =>
array (size=4)
0 => string 'BHG-MS-AHR030720' (length=16)
1 => string 'BHG-MS-AHR030720-A5' (length=19)
2 => string 'BHG-MS-AHR030720-A4' (length=19)
3 => string 'BHG-MS-AHR030720-A3' (length=19)
4 =>
array (size=4)
0 => string 'Autism House Rules' (length=18)
1 => string 'Autism House Rules - 150mm x 200mm' (length=34)
2 => string 'Autism House Rules - 201mm x 305mm' (length=34)
3 => string 'Autism House Rules - 305mm x 400mm' (length=34)
5 =>
array (size=4)
0 => string 'Autism House Rules' (length=18)
1 => string 'Autism House Rules' (length=18)
2 => string 'Autism House Rules' (length=18)
3 => string 'Autism House Rules' (length=18)
6 =>
array (size=3)
1 => string 'BHG-MS-AHR030720' (length=16)
2 => string 'BHG-MS-AHR030720' (length=16)
3 => string 'BHG-MS-AHR030720' (length=16)
6 =>
array (size=2)
0 => string '' (length=0)
1 => string '' (length=0)
7 =>
array (size=2)
0 => string '' (length=0)
1 => string '' (length=0)
8 =>
array (size=2)
0 => string '' (length=0)
1 => string '' (length=0)
9 =>
I have tried multiple ways to get this to work and this is the closest I have got to it being correct
$f = fopen('new.csv', 'a'); // Configure fOpen to create, open and write only.
if ($f != false){
// Loop over the array and passing in the values only.
foreach ($the_big_array as $row){
fputcsv($f, $row);
}
}
fclose($f);
This gives me this layout but it just shows there is a child array and does not output the data of the child arrays.
Above is the output I am getting.
Below is the layout I want to achieve.
I have also tried a foreach loop inside a foreach loop to get the data, when I do this I get all the data but not in the same layout. I have looked through all the posts on here and so many get close to what I want to achieve but none of them give the correct layout.
To summarise, I want to export $the_big_array to a .csv file that has the layout of the second image of a .csv in a spreadsheet. Thank you
array (
0 =>
array (
0 => 'Title',
1 => 'image_url',
3 => 'SKU CODE',
4 => 'TITLE SIZE',
5 => 'DESCRIPTION',
6 => 'BASE SKU',
),
1 =>
array (
0 => 'A witch and her cat live here',
1 => 'https://beautifulhomegifts.com/a-witch-and-her-cat-live-here/',
3 =>
array (
0 => 'BHG-MS-AWAHCLH030720',
1 => 'BHG-MS-AWAHCLH030720-A5',
2 => 'BHG-MS-AWAHCLH030720-A4',
3 => 'BHG-MS-AWAHCLH030720-A3',
),
4 =>
array (
0 => 'A witch and her cat live here',
1 => 'A witch and her cat live here - 150mm x 200mm',
2 => 'A witch and her cat live here - 201mm x 305mm',
3 => 'A witch and her cat live here - 305mm x 400mm',
),
5 =>
array (
0 => 'A witch and her cat live here',
1 => 'A witch and her cat live here',
2 => 'A witch and her cat live here',
3 => 'A witch and her cat live here',
),
6 =>
array (
1 => 'BHG-MS-AWAHCLH030720',
2 => 'BHG-MS-AWAHCLH030720',
3 => 'BHG-MS-AWAHCLH030720',
),
),
2 =>
array (
0 => '',
1 => '',
),
3 =>
array (
0 => '',
1 => '',
),
4 =>
array (
0 => '',
1 => '',
),
5 =>
array (
0 => 'Autism House Rules',
1 => 'https://beautifulhomegifts.com/autism-house-rules/',
3 =>
array (
0 => 'BHG-MS-AHR030720',
1 => 'BHG-MS-AHR030720-A5',
2 => 'BHG-MS-AHR030720-A4',
3 => 'BHG-MS-AHR030720-A3',
),
4 =>
array (
0 => 'Autism House Rules',
1 => 'Autism House Rules - 150mm x 200mm',
2 => 'Autism House Rules - 201mm x 305mm',
3 => 'Autism House Rules - 305mm x 400mm',
),
5 =>
array (
0 => 'Autism House Rules',
1 => 'Autism House Rules',
2 => 'Autism House Rules',
3 => 'Autism House Rules',
),
6 =>
array (
1 => 'BHG-MS-AHR030720',
2 => 'BHG-MS-AHR030720',
3 => 'BHG-MS-AHR030720',
),
),
Ok since the array is malformed and the code is a bit lengthy, I would like to say that we
First, print the headers by popping the first entry in the array.
Make each row have same number of entries by getting the max depth/ max count that a row entry could go with entry values.
Print each new row which is symmetrically arranged by using array_column(). You can print $final_row_data in the code to get a better view of how it is symmeterically arranged.
Snippet:
<?php
$the_big_array = array (
0 =>
array (
0 => 'Title',
1 => 'image_url',
3 => 'SKU CODE',
4 => 'TITLE SIZE',
5 => 'DESCRIPTION',
6 => 'BASE SKU',
),
1 =>
array (
0 => 'A witch and her cat live here',
1 => 'https://beautifulhomegifts.com/a-witch-and-her-cat-live-here/',
3 =>
array (
0 => 'BHG-MS-AWAHCLH030720',
1 => 'BHG-MS-AWAHCLH030720-A5',
2 => 'BHG-MS-AWAHCLH030720-A4',
3 => 'BHG-MS-AWAHCLH030720-A3',
),
4 =>
array (
0 => 'A witch and her cat live here',
1 => 'A witch and her cat live here - 150mm x 200mm',
2 => 'A witch and her cat live here - 201mm x 305mm',
3 => 'A witch and her cat live here - 305mm x 400mm',
),
5 =>
array (
0 => 'A witch and her cat live here',
1 => 'A witch and her cat live here',
2 => 'A witch and her cat live here',
3 => 'A witch and her cat live here',
),
6 =>
array (
1 => 'BHG-MS-AWAHCLH030720',
2 => 'BHG-MS-AWAHCLH030720',
3 => 'BHG-MS-AWAHCLH030720',
),
),
2 =>
array (
0 => '',
1 => '',
),
3 =>
array (
0 => '',
1 => '',
),
4 =>
array (
0 => '',
1 => '',
),
5 =>
array (
0 => 'Autism House Rules',
1 => 'https://beautifulhomegifts.com/autism-house-rules/',
3 =>
array (
0 => 'BHG-MS-AHR030720',
1 => 'BHG-MS-AHR030720-A5',
2 => 'BHG-MS-AHR030720-A4',
3 => 'BHG-MS-AHR030720-A3',
),
4 =>
array (
0 => 'Autism House Rules',
1 => 'Autism House Rules - 150mm x 200mm',
2 => 'Autism House Rules - 201mm x 305mm',
3 => 'Autism House Rules - 305mm x 400mm',
),
5 =>
array (
0 => 'Autism House Rules',
1 => 'Autism House Rules',
2 => 'Autism House Rules',
3 => 'Autism House Rules',
),
6 =>
array (
1 => 'BHG-MS-AHR030720',
2 => 'BHG-MS-AHR030720',
3 => 'BHG-MS-AHR030720',
),
)
);
$headers = array_shift($the_big_array);
$header_keys = array_keys($headers);
$fhandle = fopen("sample.csv","a+");// have w+ if you want to override each time.
fputcsv($fhandle,$headers);// add headers first
foreach($the_big_array as $row_data){
$insert_row = [];
// making consistent with all header keys
foreach($header_keys as $key){
if(isset($row_data[$key])){
$insert_row[$key] = $row_data[$key];
}else{
$insert_row[$key] = '';
}
}
if(count(array_filter($insert_row)) == 0) continue;
$final_row_data = [];
$max_depth_size = 0;
foreach($insert_row as $value){
if(is_array($value)){
$max_depth_size = max($max_depth_size,count($value));
}
}
foreach($insert_row as $key => $value){
$temp = [];
if(is_array($value)){
$value = array_values($value); // since data is malformed(would work even if it is ok)
$val_size = count($value);
for($i = 0; $i < $max_depth_size; ++$i){
if($i >= $val_size) $temp[$i] = '';
else $temp[$i] = $value[$i];
}
}else{
$temp = array_merge(array($value),array_fill(0, $max_depth_size - 1, ''));
}
$final_row_data[] = $temp;
}
for($column = 0;$column < $max_depth_size; ++$column){
fputcsv($fhandle,array_column($final_row_data, $column)); // add all formatted data to CSV
}
}
fclose($fhandle);
Your starting array is bad-formed, because it is not consistent in the dimensions of the child array and in the indexes. That's a valid solution, but it's very fragile because there are a lot of assumption about the array structure.
$f = fopen('new.csv', 'a');
// Write the header
fputcsv($f, array_values(array_shift($the_big_array)));
foreach($the_big_array as $baseRow) {
if (empty($baseRow[0]) continue
$subRowsCount = count($baseRow[3])
if (
count($baseRow[4]) !== $subRowsCount
|| count($baseRow[5]) !== $subRowsCount
|| count($baseRow[6]) !== $subRowsCount - 1)
} {
// Check that the sub-arrays dimensions are consistent or ignore the row
continue;
}
for($i = 0; $i < $subRowsCount; $i++) {
fputcsv($f, [
$i === 0 ? $baseRow[0] : '', // Title
$i === 0 ? $baseRow[1] : '', // image_url
$baseRow[3][$i], // SKU code
$baseRow[4][$i], // Title size
$baseRow[5][$i], // Description
$i === 0 ? '' : $baseRow[6][$i-1] // Base sku
])
}
}
The first row of each "group" contains the max number of columns so it can be used to reliably fetch column data.
Tear off the title and url values as you iterate your input array so that the remaining data in the subarray has a consistent and easily manipulated structure.
Rows that have missing trailing columns do not matter when pushing csv rows into a file, so it is a waste of code to bother generating empty strings. Conversely, leading empty column values will be a problem -- this is why I add two empty strings when not adding the first row of a respective group.
Read the PSR coding standards to see recommendations on spacing and curly brace usage.
Code: (Demo)
$headers = array_shift($array);
$fhandle = fopen("new.csv", "a");
fputcsv($fhandle, $headers);
foreach ($array as $row) {
if (empty($row[0])) {
continue;
}
$titleAndUrl = array_splice($row, 0, 2);
foreach ($row[0] as $column => $notUsed) {
fputcsv(
$fhandle,
array_merge(
!$column ? $titleAndUrl : ['', ''],
array_column($row, $column)
)
);
}
}
fclose($fhandle);
See demo for output in array form.
I got this string below.
string(49) "02/12/2018 (Assessment 2) = /86= | Weight: 50.00%"
string(49) "02/12/2018 (Assessment 2) = 50.83/86= | Weight: 50.00%""
The first example don't show any number before the /, in this case I need to use 00.00 as the default value.
I need to get this information and put in an array like this one:
$dados[ "date" ] = "02/12/2018"
$dados[ "markOK" ] = "50"
$dados[ "markTotal" ] = "86"
$dados[ "weight" ] = "50.00"
Other examples:
string(49) "02/12/2018 (Assessment 2) = /86= | Weight: 50.00%"
string(59) "06/11/2018 (Assessment 2) = 22.40/35=32.00 | Weight: 50.00%"
string(49) "04/12/2018 (Assessment 2) = /60= | Weight: 50.00%"
string(59) "11/09/2018 (Assessment 2) = 27.00/40=33.75 | Weight: 50.00%"
string(59) "09/09/2018 (Assessment 2) = 30.00/30=50.00 | Weight: 50.00%"
string(59) "14/08/2018 (Assessment 2) = 31.00/40=38.75 | Weight: 50.00%"
string(59) "19/06/2018 (Assessment 2) = 63.00/72=43.75 | Weight: 50.00%"
string(59) "17/06/2018 (Assessment 2) = 45.00/45=50.00 | Weight: 50.00%"
string(59) "22/05/2018 (Assessment 2) = 11.00/55=10.00 | Weight: 50.00%"
Like this:
(?P<date>\d{2}\/\d{2}\/\d{4})[^=]+=\s(?P<markOK>\d+(?:\.\d+)?)?\/(?P<markTotal>\d+)[^:]+:\s(?P<weight>\d+(?:\.\d+)?)
Test online
It's actually pretty simple.
(?P<date>\d{2}\/\d{2}\/\d{4}) capture the date
[^=]+=\s skip everything not an equal then the equal and a space
(?P<markOK>\d+(?:\.\d+)?)? capture float (optional)
\/ the slash
(?P<markTotal>\d+) capture integer
[^:]+:\s skip everything not a colon then the colon and a space
(?P<weight>\d+(?:\.\d+)?) capture float
Update
$pattern = '/(?P<date>\d{2}\/\d{2}\/\d{4})[^=]+=\s(?P<markOK>\d+(?:\.\d+)?)?\/(?P<markTotal>\d+)[^:]+:\s(?P<weight>\d+(?:\.\d+)?)/';
if(preg_match($pattern, $str, $matches)){
var_export($matches);
}
If you want to clean up the matches array you can do it like this:
$str = '04/12/2018 (Assessment 2) = /60= | Weight: 50.00%';
$pattern = '/(?P<date>\d{2}\/\d{2}\/\d{4})[^=]+=\s(?P<markOK>\d+(?:\.\d+)?)?\/(?P<markTotal>\d+)[^:]+:\s(?P<weight>\d+(?:\.\d+)?)/';
if(preg_match($pattern, $str, $matches)){
$default = [
'date' => '00/00/0000',
'markOK' => '0.00',
'markTotal' => '0',
'weight' => '0.00'
];
$matches = array_filter($matches);
$matches = array_merge($default, array_intersect_key($matches, $default));
var_export($matches);
}
Try it online
Output
array (
'date' => '04/12/2018',
'markOK' => '0.00',
'markTotal' => '60',
'weight' => '50.00',
)
While using named capture groups certainly has purpose for this case, I find the syntax makes the pattern unnecessarily bloated and harder to read. After matching the substrings (notably the optional 2nd substring), you'll need to write a condition to replace the zero-length string with 00.00.
Here's what I recommend:
Code: (PHP Demo) (Regex Demo)
$strings = [
"02/12/2018 (Assessment 2) = /86= | Weight: 50.00%",
"06/11/2018 (Assessment 2) = 22.40/35=32.00 | Weight: 50.00%",
"04/12/2018 (Assessment 2) = /60= | Weight: 50.00%",
"11/09/2018 (Assessment 2) = 27.00/40=33.75 | Weight: 50.00%",
"09/09/2018 (Assessment 2) = 30.00/30=50.00 | Weight: 50.00%",
"14/08/2018 (Assessment 2) = 31.00/40=38.75 | Weight: 50.00%",
"19/06/2018 (Assessment 2) = 63.00/72=43.75 | Weight: 50.00%",
"17/06/2018 (Assessment 2) = 45.00/45=50.00 | Weight: 50.00%",
"22/05/2018 (Assessment 2) = 11.00/55=10.00 | Weight: 50.00%"
];
foreach ($strings as $string) {
if (!preg_match('~(\d\d/\d\d/\d{4})[^=]+= (\d+(?:\.\d+)?)?/(\d+)[^:]+: (\d+(?:\.\d+)?)~', $string, $m)) {
echo "No match for string: $string\n";
} else {
$results[] = ['date' => $m[1], 'markOK' => strlen($m[2]) ? $m[2] : '00.00', 'markTotal' => $m[3], 'weight' => $m[4]];
}
}
var_export($results);
Output:
array (
0 =>
array (
'date' => '02/12/2018',
'markOK' => '00.00',
'markTotal' => '86',
'weight' => '50.00',
),
1 =>
array (
'date' => '06/11/2018',
'markOK' => '22.40',
'markTotal' => '35',
'weight' => '50.00',
),
2 =>
array (
'date' => '04/12/2018',
'markOK' => '00.00',
'markTotal' => '60',
'weight' => '50.00',
),
3 =>
array (
'date' => '11/09/2018',
'markOK' => '27.00',
'markTotal' => '40',
'weight' => '50.00',
),
4 =>
array (
'date' => '09/09/2018',
'markOK' => '30.00',
'markTotal' => '30',
'weight' => '50.00',
),
5 =>
array (
'date' => '14/08/2018',
'markOK' => '31.00',
'markTotal' => '40',
'weight' => '50.00',
),
6 =>
array (
'date' => '19/06/2018',
'markOK' => '63.00',
'markTotal' => '72',
'weight' => '50.00',
),
7 =>
array (
'date' => '17/06/2018',
'markOK' => '45.00',
'markTotal' => '45',
'weight' => '50.00',
),
8 =>
array (
'date' => '22/05/2018',
'markOK' => '11.00',
'markTotal' => '55',
'weight' => '50.00',
),
)
I need to insert data to a table.. the data come from different sources. The following are my code.
$title = array(Book A, Book B, Book C);
$number = array(2,1,4);
$lines = array(Maria, Smith, Abner);
for($i=1; $i<count($lines); $i++)
{
print '<tr>';
print '<td>'.$title[$i].'</td>';
print '<td>P'.$number[$i].'</td>';
print '<td>['.$lines[$i].']</td>';
print '<td></td>';
print '</tr>';
}
Seems not working :/ the array not display properly in my table.
I'm expecting output as follows:
------------------------------------------------
| Title | No | Lines | Remarks |
------------------------------------------------
| Book A | 2 | Maria | |
| Book B | 1 | Smith | |
| Book C | 4 | Abner | |
------------------------------------------------
at the moment.. I get the following output:
------------------------------------------------
| Title | No | Lines | Remarks |
------------------------------------------------
| Book A | 2 | Maria | |
| | | Smith | |
| | | Abner | |
------------------------------------------------
If your arrays has different keys you can 'reset' them to be zero-based. Just use $array = array_values($array). Quote from manual
array_values() returns all the values from the array and indexes the array numerically.
After this you code will work. This is how your example can be modified:
$title = array('Book A', 'Book B', 'Book C');
$number = array("a" => 2, "b" => 1, "c" => 4);
$lines = array('Maria', 'Smith', 7 => 'Abner');
/* At this point you have some arrays with unknown keys.
It can be [0 => item, 1 => item2] or ['name' => item, 'name2' => item2]
or even with skipped keys [0 => item, 7 => item2]
*/
// Reset keys for all arrays. Now all arrays will contain keys 0, 1, 2 etc.
$title = array_values($title);
$number = array_values($number);
$lines = array_values($lines);
for($i = 0; $i < count($lines); $i++) // Note, arrays now are zero-based, you must start from $i = 0
{
print '<tr>';
print '<td>'.$title[$i].'</td>';
print '<td>P'.$number[$i].'</td>';
print '<td>['.$lines[$i].']</td>';
print '<td></td>';
print '</tr>';
}
you just put i=0; because array started from 0 index and try following code may it help u.
<?php $title = array('Book A','Book B','BookC');$number = array('2','1','4');$lines = array('Maria','Smith','Abner');for($i=0;$i<count($lines); $i++){print '<tr>';print '<td>'.$title[$i].'</td>';print '<td>P'.$number[$i].'</td>';print'<td>['.$lines[$i].']</td>';print '<td></td>'; print '</tr>'; } ?>
There's a neat trick to merging separate arrays with array_map() if you pass null as the first argument, followed by the arrays you want merged.
As quoted in Example #4 in the docs:
An interesting use of this function is to construct an array of arrays, which can be easily performed by using NULL as the name of the callback function
Using your example for context:
<?php
$titles = ['Book A', 'Book B', 'Book C'];
$numbers = [2,1,4];
$lines = ['Maria', 'Smith', 'Abner'];
// create an 'array of arrays'
$rows = array_map(null, $titles, $numbers, $lines);
var_dump($rows);
Yields:
array (size=3)
0 =>
array (size=3)
0 => string 'Book A' (length=6)
1 => int 2
2 => string 'Maria' (length=5)
1 =>
array (size=3)
0 => string 'Book B' (length=6)
1 => int 1
2 => string 'Smith' (length=5)
2 =>
array (size=3)
0 => string 'Book C' (length=6)
1 => int 4
2 => string 'Abner' (length=5)
You can then iterate over it pretty easily, like so:
foreach ($rows as $row) {
list($title, $number, $line) = $row;
printf('<tr><td>%s</td><td>%s</td><td>%s</td></tr>',
$title, $number, $line);
}
This should give you something like:
<tr><td>Book A</td><td>2</td><td>Maria</td></tr>
<tr><td>Book B</td><td>1</td><td>Smith</td></tr>
<tr><td>Book C</td><td>4</td><td>Abner</td></tr>
A useful side-effect of this approach is that your arrays do not have to be the same length; null will be used where applicable to pad out any "missing" values.
Another quick example:
<?php
$letters = range('a', 'd'); // ['a', 'b', 'c', 'd']
$numbers = range(1, 3); // [1, 2, 3]
$merged = array_map(null, $letters, $numbers);
var_dump($merged);
Yields:
array (size=4)
0 =>
array (size=2)
0 => string 'a' (length=1)
1 => int 1
1 =>
array (size=2)
0 => string 'b' (length=1)
1 => int 2
2 =>
array (size=2)
0 => string 'c' (length=1)
1 => int 3
3 =>
array (size=2)
0 => string 'd' (length=1)
1 => null
Hope this helps :)
You can try modifying you code as follow:
foreach($lines as $z => $value)
{
print '<tr>';
print '<td>'.$title[$z].'</td>';
print '<td>P'.$number[$z].'</td>';
print '<td>['.$value.']</td>';
print '<td></td>';
print '</tr>';
}
I found that the array index for all my array is not in sequential.
eg: $title =
array[0] = Book A
array[5] = Book B
array[9] = Book C
So, that is probably the reason why it is not display accordingly. I cannot use function 'for'. However, I cannot re-number the index because its the key for me to continue with next module/function.
So, I tried the following code.. but seems something missing..
$i=0;
if (!empty($title)){
foreach($title as $key => $value){
$y = $number[$key];
if ($i<count($lines))
{ $z = $lines[$i];
$i+1;
}
print '<tr>';
print '<td>'.$value.'</td>';
print '<td>'.$y.'</td>';
print '<td>['.$z.']</td>';
print '<td></td>';
print '</tr>';
}
}
The following is the output that I get. Now array for $lines that didn't display properly.
------------------------------------------------
| Title | No | Lines | Remarks |
------------------------------------------------
| Book A | 2 | Maria | |
| Book B | 1 | Maria | |
| Book C | 4 | Maria | |
------------------------------------------------
This question already has answers here:
How to have a stable sort in PHP with arsort()?
(7 answers)
Closed 9 years ago.
There is strange issue in php asort, arsort.
I am taking example of arsort
Case1
$a = array(
1 => 2,
2 => 1,
3 => 2,
4 => 1
);
arsort($a);
var_dump($a);
Output:
array(4) {
[3] =>
int(2)
[1] =>
int(2)
[4] =>
int(1)
[2] =>
int(1)
}
Here at index (3,1) and (4,2) are sorted in descending order because at index 3 and 1 values are same. Same for index 4 and 2.
Case2
$a = array(
1 => 2,
2 => 1,
3 => 2
);
arsort($a);
var_dump($a);
Output:
array(3) {
[1] =>
int(2)
[3] =>
int(2)
[2] =>
int(1)
}
Here at index (3,1) are sorted in ascending order and still at index 3 and 1 values are same.
Is there any solution for this issue? As I want that ordering should be certain. Like sort in either descending or ascending order if value at some indices are same.
According to the PHP documentation:
If any of these sort functions evaluates two members as equal then the order is undefined (the sorting is not stable).
You can't know exactly which behaviour is correct, with testing just with 2 elements. Here's an array with multiple elements (odd and even).
even number:
<?php
$a = array(
1 => 2,
2 => 1,
3 => 2,
4 => 1,
5 => 2,
6 => 1,
7 => 2,
8 => 1,
9 => 2,
10 => 1,
11 => 2,
12 => 1
);
arsort($a);
var_dump($a);
Result:
array (size=12)
1 => int 2
7 => int 2
5 => int 2
11 => int 2
9 => int 2
3 => int 2
10 => int 1
12 => int 1
6 => int 1
2 => int 1
4 => int 1
8 => int 1
odd number
<?php
$a = array(
1 => 2,
2 => 1,
3 => 2,
4 => 1,
5 => 2,
6 => 1,
7 => 2,
8 => 1,
9 => 2,
10 => 1,
11 => 2,
12 => 1,
13 => 2
);
arsort($a);
var_dump($a);
Result
array (size=13)
9 => int 2
11 => int 2
13 => int 2
1 => int 2
7 => int 2
3 => int 2
5 => int 2
12 => int 1
2 => int 1
4 => int 1
8 => int 1
6 => int 1
10 => int 1
The question is now, where did it add the 13th element (=2)? it's added just after the 11th element and before the first element...this means that there's no rule here. (At least according to what we see).
We can't say that it follows any rule with testing with just 2 variables like what you did, because you saw (1,3) and you presumed that it's sorted by key. Which is apparently not the case with multiple variables.
I am two arrays both containning 4 keyed values. They both have the same columns - how would I merge them like so:
Array 1:
Author|Download|Rating|Count
person|23 | 5 | 0
peter |45 | 4 | 0
Array 2:
Author|Download|Rating|Count
| 0 |0 | 3
| 0 |0 | 5
Becomes a single array:
Author|Download|Rating|Count
person|23 | 5 | 3
peter |45 | 4 | 5
This is done via two SQL Queries like shown:
Array 1
while ($stmt->fetch())
{
$array = array (
'Author' => $author,
'Download' => $download,
'Rating' => $rating,
'Count' => '',
);
}
Array 2
while ($stmt->fetch())
{
$array = array (
'Author' => '',
'Download' => '',
'Rating' => '',
'Count' => $count,
);
}
How would I get these into a single Array?
I know one could do this via loop but is there an easier way to do this?