How to convert multidimensional array to string - php

I have a requirement to gather all the comments of posts and show them in CSV.
For that, I have this kind of array ( post-wise ) :
[21069] => Array
(
[0] => Array
(
[comment_author] => author1
[comment_content] => for testing
)
[1] => Array
(
[comment_author] => author2
[comment_content] => this is
)
[2] => Array
(
[comment_author] => author3
[comment_content] => good
)
)
[21070] => Array
(
[0] => Array
(
[comment_author] => author4
[comment_content] => file reading
)
[1] => Array
(
[comment_author] => author5
[comment_content] => hi
)
)
I want to show this data in CSV , for that, I need to convert the array into a string in this form.
[0]=>Array
(
['author_comment']=>'author1:for testing|author2:this is|author3:good'
)
[1]=>Array
(
['author_comment']=>'author4:file reading|author5:hi'
)
I am not getting how do I use implode function.
EDIT 1 : Please find var_export in below code.
$newArray = [
'21069' => [
'0' => [
'comment_author' => 'author1',
'comment_content' => 'for testing'
],
'1' => [
'comment_author' => 'author2',
'comment_content' => 'this is'
],
'2' => [
'comment_author' => 'author3',
'comment_content' => 'good'
],
],
'21070' => [
'0' => [
'comment_author' => 'author4',
'comment_content' => 'file reading'
],
'1' => [
'comment_author' => 'author5',
'comment_content' => 'hi '
],
],
];

I Manage to concat the comments using below code.
$new1Array = [];
foreach($newArray as $key => $value){
foreach($value as $value1) {
$new1Array[$key][]['author_comment'] = $value1['comment_author'].':'.$value1['comment_content'];
}
}
$finalArraynew = [];
foreach($new1Array as $key => $value) {
$finalArraynew[$key][] = implode('|', array_map(function ($entry) {
return $entry['author_comment'];
}, $value));
}

Related

find duplicates value with their keys

My array is like this,
$options = Array
(
[0] => Array
(
[value] => 180
[label] => Nokia
)
[1] => Array
(
[value] => 2341
[label] => Suisses
)
[2] => Array
(
[value] => 143
[label] => Nokia
)
[3] => Array
(
[value] => 2389
[label] => 3D Pop Art
)
)
and i want output as,
Array(
[0] => Array
(
[value] => 180
[label] => Nokia
)
[2] => Array
(
[value] => 143
[label] => Nokia
)
)
Can anyone suggest me in this.
You can try something like this:
$options = [
0 => [
'value' => 180,
'label' => 'Nokia'
],
1 => [
'value' => 2341,
'label' => 'Suisses'
],
2 => [
'value' => 143,
'label' => 'Nokia'
],
3 => [
'value' => 2389,
'label' => '3D Pop Art'
],
];
$labels = [];
$duplicates = [];
foreach ($options as $option) {
if (!empty($duplicates[$option['label']])) {
$duplicates[$option['label']][] = $option;
}
if (empty($labels[$option['label']])) {
$labels[$option['label']] = $option;
} else {
$duplicates[$option['label']] = [
$labels[$option['label']],
$option
];
}
}
It seems you are looking for group by 'label'
foreach($options as $v){
$c[$v['label']][] = $v['value'];
}
print_r($c);
Working example : https://3v4l.org/62dv0
The array_filter() function is what you are looking for:
<?php
$data = [
[
'value' => 180,
'label' => "Nokia"
],
[
'value' => 2341,
'label' => "Suisses"
],
[
'value' => 143,
'label' => "Nokia"
],
[
'value' => 2389,
'label' => "3D Pop Art"
]
];
$output = [];
array_walk($input, function($entry) use (&$output) {
$output[$entry['label']][] = $entry;
});
print_r(
array_filter(
$output,
function($entry) {
return count($entry) > 1;
}
)
);
The output obviously is:
Array
(
[Nokia] => Array
(
[0] => Array
(
[value] => 180
[label] => Nokia
)
[1] => Array
(
[value] => 143
[label] => Nokia
)
)
)
That output slightly differs from the one suggested by you. But it has the advantage that you can tell entries apart by the doubled label.

I want a particular format array from an array in PHP

I want to modify the existing array to a particular format please see the below array what i have and what i want
I have array as :
Array
(
[0] => Array
(
[block_id] => 1
[title] => Test1
[identifier] => test1
[content] => some test data
[creation_time] => 2019-09-03 09:47:35
[update_time] => 2019-09-03 09:47:35
[is_active] => 1
)
[1] => Array
(
[block_id] => 2
[title] => test2
[identifier] => twst2
[content] => dfdsffsdfsdfsfsdf
[creation_time] => 2019-09-03 09:48:03
[update_time] => 2019-09-03 09:48:03
[is_active] => 1
)
)
And I want this array as :
$options = [
['value' => 'test1', 'label' => __('Test1')],
['value' => 'test2', 'label' => __('Test2')],
['value' => 'test3', 'label' => __('Test3')],
['value' => 'test4', 'label' => __('Test4')],
['value' => 'test5', 'label' => __('Test5')],
['value' => 'test6', 'label' => __('Test6')]
];
Try this Solution.
$data = Array ( Array
(
'block_id' => 1,
'title' => 'Test1'
), Array
(
'block_id' => 2,
'title' => 'test2'
)
);
foreach($data as $k => $val){
$options[$k]['value'] = $val['title'];
$options[$k]['label'] = '__("'.ucfirst($val['title']).'")';
}
echo "<pre>";
print_r( $options);
Expected Result is
Array
(
[0] => Array
(
[value] => Test1
[label] => __("Test1")
)
[1] => Array
(
[value] => test2
[label] => __("Test2")
)
)
If $array is your array, then
foreach ($array as $k => $v)
{
$options[] = [ 'value' => $v['identifier'], 'label' => "__('" . $v['title'] . "')"];
}
If you are trying "to modify the existing array to a particular format" , next approach may help. When you precede $value with &, the $value will be assigned by reference and you can directly modify it.
<?php
foreach($array as &$value) {
$value = array(
'value' => $value["identifier"],
'label' => "__('".$value["title"]."')"
);
};
unset($value);
?>
Try this Solution.
foreach ($array as $k => $val)
{
$options[] = [ 'val' => $val['identifier'], 'label' => "__('" . $val['title'] . "')"];
}

PHP - Merge 2 multidimensional array based on value

Currently, I have 2 multidimensional array and I'm looking to combine them into one giant array where the value's name in array 1 matches the value's name in array 2.
The array's look as followed...
Array1
(
[0] => Array
(
[id] => 1
[name] => test1
[desc] => test_desc
[quantity] => 3
)
[1] => Array
(
[id] => 2
[name] => test2
[desc] => test_desc
[quantity] => 33
)
)
Array2
(
[0] => Array
(
[holder] => 'John'
[name] => test1
[desc] => test_desc
[location] => ATL
)
[1] => Array
(
[holder] => 'Jackie'
[name] => test3
[desc] => test_desc
[location] => SF
)
)
I'm looking to merge the arrays where the 'name' column in array1 matches in array2 and also combine the columns in array's 1 & 2 into the final array. This should look like...
FinalArray
(
[0] => Array
(
[id] => 1
[holder] => 'John'
[name] => test1
[desc] => test_desc
[location] => ATL
[quantity] => 3
)
[1] => Array
(
[holder] => 'Jackie'
[name] => test3
[desc] => test_desc
[location] => SF
)
[2] => Array
(
[id] => 2
[name] => test2
[desc] => test_desc
[quantity] => 33
)
)
Where the "test1" combines the different columns across the 2 arrays into a new array inside the "FinalArray". I've tried researching some ideas with array_merge and array_merge_recursive but I'm not entirely sure if I'm going in the correct direction. Thanks in advance.
Try like this
$array1=[['id' => 1,'name' => 'test1','desc' => 'test_desc','quantity' => 3],
['id' => 2,'name' => 'test2','desc' => 'test_desc','quantity' => 33]];
$array2=[['holder' => 'John','name' => 'test1','desc' => 'test_desc','location' => 'ATL'],
['holder' => 'Jackie','name' => 'test3','desc' => 'test_desc','location' => 'SF']];
$final=[];
foreach ($array1 as $key1=>$data1){
foreach ($array2 as $key2=>$data2){
if($data1['name']==$data2['name']){
$final[]=$data1+$data2;
unset($array1[$key1]);
unset($array2[$key2]);
}
}
}
if(!empty($array1)){
foreach ($array1 as $value){
$final[]=$value;
}
}
if(!empty($array2)){
foreach ($array2 as $value){
$final[]=$value;
}
}
It will give output as
One more solution
function merge_by_name(array $arr1, array $arr2) {
$result = [];
foreach ($arr1 as $value) {
$key = array_search($value['name'], array_column($arr2, 'name'));
if($key !== false) {
$result[] = array_merge($value, $arr2[$key]);
unset($arr2[$key]);
} else {
$result[] = $value;
}
}
$result = array_merge($result, $arr2);
return $result;
}
Test
$arr1 = [
[
'id' => 1,
'name' => 'test1',
'desc' => 'test_desc',
'quantity' => 3
],
[
'id' => 2,
'name' => 'test2',
'desc' => 'test_desc',
'quantity' => 33
],
];
$arr2 = [
[
'holder' => 'John',
'name' => 'test1',
'desc' => 'test_desc',
'location' => 'ATL'
],
[
'holder' => 'Jackie',
'name' => 'test3',
'desc' => 'test_desc',
'location' => 'SF'
],
];
var_export(merge_by_name($arr1, $arr2));
Result
array (
0 =>
array (
'id' => 1,
'name' => 'test1',
'desc' => 'test_desc',
'quantity' => 3,
'holder' => 'John',
'location' => 'ATL',
),
1 =>
array (
'id' => 2,
'name' => 'test2',
'desc' => 'test_desc',
'quantity' => 33,
),
2 =>
array (
'holder' => 'Jackie',
'name' => 'test3',
'desc' => 'test_desc',
'location' => 'SF',
),
)

Merging multidimensional arrays by matching key-value pairs of subarrays?

The task is to merge ("inexpensively") two arrays, which have matching key-value pairs of subarrays. E.g.:
Array 1:
Array
(
[0] => Array
(
[count] => 1
[da_table] => article
[da_class] => classes\elements\tables\Article
[da_page_class] => Page_Article
)
[1] => Array
(
[count] => 2
[da_table] => client_contract_specification_price
[da_class] => classes\elements\tables\ClientContractSpecificationPrice
[da_page_class] => Page_ClientContractSpecification
)
[2] => Array
(
[count] => 2
[da_table] => supplier
[da_class] => classes\elements\tables\Supplier
[da_page_class] => Page_Supplier
)
)
Array 2:
Array
(
[0] => Array
(
[name] => Articles
[name_short] =>
[da_page_class] => Page_Article
)
[1] => Array
(
[name] => Client contract specifications
[name_short] => cc_specifications
[da_page_class] => Page_ClientContractSpecification
)
[2] => Array
(
[name] => Suppliers
[name_short] =>
[da_page_class] => Page_Supplier
)
)
How to merge the two above arrays by a matching [da_page_class] => ... pairs, so the resulting array will contain both key-values of the first and the second array, i.e.:
...
[0] => Array
(
[count] => 1
[da_table] => article
[da_class] => classes\elements\tables\Article
[da_page_class] => Page_Article
[name] => Articles
[name_short] =>
)
...
Additional requirements:
Subarrays may come in random order. Also, there can be "orphans", which contain values of ['da_page_class'], but have no match in another array. These should be ignored.
Well, you simply iterate over the array elements and combine them:
<?php
$data1 = [
[
'count' => 1,
'da_table' => 'article',
'da_class' => 'classes\elements\tables\Article',
'da_page_class' => 'Page_Article'
],
[
'count' => 2,
'da_table' => 'client_contract_specification_price',
'da_class' => 'classes\elements\tables\ClientContractSpecificationPrice',
'da_page_class' => 'Page_ClientContractSpecification'
],
[
'count' => 2,
'da_table' => 'supplier',
'da_class' => 'classes\elements\tables\Supplier',
'da_page_class' => 'Page_Supplier'
]
];
$data2 = [
[
'name' => 'Articles',
'name_short' => null,
'da_page_class' => 'Page_Article'
],
[
'name' => 'Client contract specifications',
'name_short' => 'cc_specifications',
'da_page_class' => 'Page_ClientContractSpecification'
],
[
'name' => 'Suppliers',
'name_short' => null,
'da_page_class' => 'Page_Supplier'
]
];
$output = [];
for ($i=0; $i<count($data1); $i++) {
$output[$i] = array_merge($data1[$i], $data2[$i]);
}
print_r($output);
The output obviously is:
Array
(
[0] => Array
(
[count] => 1
[da_table] => article
[da_class] => classes\elements\tables\Article
[da_page_class] => Page_Article
[name] => Articles
[name_short] =>
)
[1] => Array
(
[count] => 2
[da_table] => client_contract_specification_price
[da_class] => classes\elements\tables\ClientContractSpecificationPrice
[da_page_class] => Page_ClientContractSpecification
[name] => Client contract specifications
[name_short] => cc_specifications
)
[2] => Array
(
[count] => 2
[da_table] => supplier
[da_class] => classes\elements\tables\Supplier
[da_page_class] => Page_Supplier
[name] => Suppliers
[name_short] =>
)
)
Alternatively you could also merge the contents of the elements of the second array into the corresponding elements of the first array. That reduces the memory footprint for large data sets.
Considering the additional requirement you specified in your comment I changed the merge strategy to allow for arbitrary orders of the two sets:
<?php
$data1 = [
[
'count' => 1,
'da_table' => 'article',
'da_class' => 'classes\elements\tables\Article',
'da_page_class' => 'Page_Article'
],
[
'count' => 2,
'da_table' => 'client_contract_specification_price',
'da_class' => 'classes\elements\tables\ClientContractSpecificationPrice',
'da_page_class' => 'Page_ClientContractSpecification'
],
[
'count' => 2,
'da_table' => 'supplier',
'da_class' => 'classes\elements\tables\Supplier',
'da_page_class' => 'Page_Supplier'
]
];
$data2 = [
[
'name' => 'Articles',
'name_short' => null,
'da_page_class' => 'Page_Article'
],
[
'name' => 'Client contract specifications',
'name_short' => 'cc_specifications',
'da_page_class' => 'Page_ClientContractSpecification'
],
[
'name' => 'Suppliers',
'name_short' => null,
'da_page_class' => 'Page_Supplier'
]
];
$output = [];
array_walk($data1, function($entry, $key) use (&$output, $data2) {
$output[$key] = $entry;
foreach($data2 as $cand) {
if ($entry['da_page_class'] == $cand['da_page_class']) {
$output[$key] = array_merge($output[$key], $cand);
}
}
});
print_r($output);
The resulting output obviously is identical to above.
O(m*n) solution:
$result = array();
foreach ($array1 as $value1) {
// do not handle elements without pageclass
if (!array_key_exists('da_page_class', $value1) || !$value1['da_page_class']) {
continue;
}
foreach ($array2 as $value2) {
if (!array_key_exists('da_page_class', $value2) || !$value2['da_page_class']) {
continue;
}
if ($value1['da_page_class'] == $value2['da_page_class']) {
array_push($result, $value1 + $value2)
break;
}
}
}
print_r($result);
O(m+n) solution:
$result = array();
foreach ($array1 as $value) {
// do not handle elements without pageclass
if (!array_key_exists('da_page_class', $value) || !$value['da_page_class']) {
continue;
}
$result[$value['da_page_class']] = $value;
}
foreach ($array2 as $value) {
if (
// do not handle elements without pageclass
!array_key_exists('da_page_class', $value) || !$value['da_page_class'] ||
// do not handle elements that do not exist in array 1
!array_key_exists($value['da_page_class'], $result)
) {
continue;
}
// merge values of this pageclass
$result[$value['da_page_class']] = array_merge($result[$value['da_page_class']], $value);
}
print_r($result);
EDIT: added O(m+n) solution

How to remove main index from array while having any value blank multidimensional array

How to remove main array index ,
ex.
original array
[4] => Array
(
[fullname] => chaman pura
[email] => chamana#gmail.com
)
[5] => Array
(
[fullname] => sagar one
[email] =>
)
[6] => Array
(
[fullname] => hello how
[email] => how#gmail.com
)
Output should be :
[4] => Array
(
[fullname] => chaman pura
[email] => chamana#gmail.com
)
[6] => Array
(
[fullname] => hello how
[email] => how#gmail.com
)
tried :
$postArr = array_map('array_filter', $postArr);
$postArr = array_filter( $postArr );
and its giving
[5] => Array
(
[fullname] => sagar one
)
its only removing child key, not removing parent index
You only have to use array_filter:
$arr = [ '4' => [ 'fullname' => 'chaman pura', 'email' => 'chamana#gmail.com' ],
'5' => [ 'fullname' => 'sagar one', 'email' => '' ],
'6' => [ 'fullname' => 'hello how', 'email' => 'how#gmail.com' ] ];
var_dump(array_filter($arr, function ($i) { return !empty($i['email']); }));
You will need to loop the array as far as I can ponder and check the internal arrays email.
$postArr = [
["fullname" => "chaman pura", "email" => "chamana#gmail.com"],
["fullname" => "sagar one", "email" => ""],
["fullname" => "hello how", "email" => "how#gmail.com"]
];
$postArrLen = count($postArr);
for($i=0; $i < $postArrLen; $i++){
if(empty($postArr[$i]['email'])){
unset($postArr[$i]);
}
}
print_r($postArr);
Additional
I suppose this could have just been a foreach
foreach($postArr as $arr){
if(empty($arr['email'])){
unset($arr);
}
}

Categories