Merge Parent child array - php

I have PHP array. I am trying to convert into a parent-child array:
I have used a recursive function but not getting my output.
Array
(
[0] => Array
(
[id] => 1
[subscription_name] => Yearly
[parent_id] => 0
)
[1] => Array
(
[id] => 22
[subscription_name] => Yearly new
[parent_id] => 1
)
[2 => Array
(
[id] => 23
[subscription_name] => Yearly new offer
[parent_id] => 22
)
[3] => Array
(
[id] => 24
[subscription_name] => Weekly
[parent_id] => 0
)
[4] => Array
(
[id] => 25
[subscription_name] => Weekly new offer
[parent_id] => 24
)
)
I expect this result
Array
(
[0] => Array
(
[id] => 1
[subscription_name] => Yearly new offer
[childrens] => Array
(
[0] => Array
(
[id] => 22
)
[1] => Array
(
[id] => 23
)
)
)
[1] => Array
(
[id] => 24
[subscription_name] => Weekly new offer
[childrens] => Array
(
[0] => Array
(
[id] => 25
)
)
)
)
I have tried but not getting my desire Output
My PHP function is
function tree(array $elements, $parent_id = 0) {
echo "<pre>";
$branch = array();
$a=array();
foreach ($elements as $element) {
if ($element['parent_id'] == $parent_id && $element['subscription_type_id'] !=1 ) {
$children = $this->tree($elements, $element['id']);
if ($children) {
$element['children'] = $children;
}
else {
$element['children'] = array();
}
$branch[] = $element;
}
}
return $branch;
}
Here is the output I am getting from the above function:
Array
(
[0] => Array
(
[id] => 1
[subscription_name] => Yearly
[children] => Array
(
[0] => Array
(
[id] => 22
[subscription_name] => Yearly new
[children] => Array
(
[0] => Array
(
[id] => 23
[subscription_name] => Yearly new offer
[children] => Array
(
)
)
)
)
)
)
[1] => Array
(
[id] => 24
[subscription_name] => Weekly
[children] => Array
(
[0] => Array
(
[id] => 25
[subscription_name] => Weekly new offer
[children] => Array
(
)
)
)
)
Please help me to solve this problem.
Thanks.

Really, i mean REALLY naive version but by the way, your data would be really more easy to exploit, like don't have any parent_id to 0 if it's not a parent Id (NULL for example) I also do not understand why do you have different subscription_name. I think you should work more on change your input instead of find a complexe algorithm to parse them
function tree(array $elements) {
$openList = [];
$result = [];
$id = 0;
foreach ($elements as $key => $element) {
if($key != 0) // I suppose the trial one is not used
{
if($element['parent_id'] == 0) // a root
{
$closeList = [];
$openList[$element['id']] = $element['id'];
$result[$id] = $element;
unset($result[$id]['parent_id']);
$result[$id]['children'] = [];
$newOpenlist = [];
while(count($openList) > 0)
{
foreach ($elements as $key => $element) {
if($element['parent_id'] != 0 && in_array($element['parent_id'], $openList) && !in_array($element['parent_id'], $closeList))
{
$newOpenlist[$element['id']] = $element['id'];
$result[$id]['children'][] = $element;
}
}
foreach($openList as $item)
{
$closeList[] = $item;
}
$openList = $newOpenlist;
$newOpenlist = [];
}
}
$id++;
}
}
return $result;
}

From your question, I do not clearly understand the logic behind the subscription_name. Regarding the childrens below code might work.
<?php
$array = [
[
'id' => 1,
'subscription_name' => 'Yearly',
'parent_id' => 0
],
[
'id' => 22,
'subscription_name' => 'Yearly new',
'parent_id' => 1
],
[
'id' => 23,
'subscription_name' => 'Yearly new offer',
'parent_id' => 22
],
[
'id' => 24,
'subscription_name' => 'Weekly',
'parent_id' => 0
],
[
'id' => 25,
'subscription_name' => 'Weekly new offer',
'parent_id' => 24
],
];
function find_childrens_parent_not_zero($array) {
foreach($array as $key => $value) {
if($value['parent_id'] != 0) {
if(!is_array($array[$key]['childrens'])) {
$array[$key]['childrens'] = [];
}
foreach($array as $k => $v) {
if($v['parent_id'] == $value['id']) {
array_push($array[$key]['childrens'], array('id' => $v['id']));
unset($array[$k]['parent_id']);
}
}
}
}
return $array;
}
function find_childrens_parent_zero($array) {
foreach($array as $key => $value) {
if($value['parent_id'] == 0) {
if(!is_array($array[$key]['childrens'])) {
$array[$key]['childrens'] = [];
}
foreach($array as $k => $v) {
if($v['parent_id'] == $value['id']) {
array_push($array[$key]['childrens'], array('id' => $v['id']));
unset($array[$k]['parent_id']);
}
}
}
}
return $array;
}
function merge_children($array) {
foreach($array as $key => $value) {
if($value['parent_id'] == 0) {
//pluck childrens of it's children
foreach($value['childrens'] as $k => $v) {
foreach($array as $ke => $val) {
if($v['id'] == $val['id']) {
$array[$key]['childrens'] = array_merge($array[$key]['childrens'], $array[$ke]['childrens']);
}
}
}
}
}
return $array;
}
/**
* Remove parent not zero elements
*/
function cleanup_array($array) {
$result = [];
foreach($array as $key => $value) {
if(array_key_exists('parent_id', $value )) {
unset($value['parent_id']);
array_push($result, $value);
}
}
return $result;
}
echo '<pre>';
$result_parent_not_zero = find_childrens_parent_not_zero($array);
$result_parent_zero = find_childrens_parent_zero($result_parent_not_zero);
$result_merged_children = merge_children($result_parent_zero);
$result_cleaned_up = cleanup_array($result_merged_children);
print_r($result_cleaned_up);
Will give you the result as
<pre>Array
(
[0] => Array
(
[id] => 1
[subscription_name] => Yearly
[childrens] => Array
(
[0] => Array
(
[id] => 22
)
[1] => Array
(
[id] => 23
)
)
)
[1] => Array
(
[id] => 24
[subscription_name] => Weekly
[childrens] => Array
(
[0] => Array
(
[id] => 25
)
)
)
)

<?php
$load[0]['id'] = 0;
$load[0]['subscription_name'] = 'Trial';
$load[0]['parent_id'] = 0;
$load[1]['id'] = 1;
$load[1]['subscription_name'] = 'Yearly';
$load[1]['parent_id'] = 0;
$load[2]['id'] = 2;
$load[2]['subscription_name'] = 'Trial';
$load[2]['parent_id'] = 1;
$load[3]['id'] = 3;
$load[3]['subscription_name'] = 'Yearly';
$load[3]['parent_id'] = 1;
$load[4]['id'] = 4;
$load[4]['subscription_name'] = 'Trial';
$load[4]['parent_id'] = 2;
function tree($load){
$output = [];
foreach($load as $l){
$temp = [];
foreach($load as $ll){
if($ll['parent_id']==$l['id']){
if($l['id']==$ll['id'])
continue;
$temp[] = $ll;
}
}
$l['childrens'] = $temp;
$output[] = $l;
}
return $output;
}
echo "<pre>";
print_r(tree($load));

Related

Two-dimensional array to multidimensional array

This is what I have:
[courses] => array
(
array([id]=>1,[name]=>"course_1",[age]=>16,[location]=>"Berlin"),
array([id]=>2,[name]=>"course_1",[age]=>18,[location]=>"Berlin"),
array([id]=>3,[name]=>"course_1",[age]=>20,[location]=>"Berlin"),
array([id]=>4,[name]=>"course_1",[age]=>16,[location]=>"London"),
array([id]=>5,[name]=>"course_1",[age]=>18,[location]=>"Rome"),
array([id]=>6,[name]=>"course_2",[age]=>16,[location]=>"Berlin")
);
What I need is to transform this into a multidimensional array like this:
- each name can have multiple ages
- each age can have multiple locations
- id is not needed
So the new transformed array should have courses that have multiple ages that have multiple locations.
I first tried to create an array for each key:
// all courses, sorted, once
$x = 0;
$course_names = array();
foreach ($courses as $item) {
$course_names[$x] = $item['name'];
$x++;
}
$course_names = array_unique($course_names);
sort($course_names);
// all ages, sorted, once
$x = 0;
$ages = array();
foreach ($courses as $item) {
$ages[$x] = $item['age'];
$x++;
}
$ages = array_unique($ages);
sort($ages);
// all locations, sorted, once
$x = 0;
$locations = array();
foreach ($courses as $item) {
$locations[$x] = $item['location'];
$x++;
}
$location = array_unique($location);
sort($location);
Then I tried to create another array as requested (don't swear at me, is one of many tries):
$counter = 0;
foreach ($location as $loc_key=>$loc_val) {
foreach ($ages as $age_key=>$age_val) {
foreach ($course_names as $cou_key=>$cou_val) {
foreach ($courses as $course) {
if ($course['name']==$cou_val) {
if ($course['age']==$age_val) {
if ($course['location']==$loc_val) {
$final_json[$counter]['ages']['locations'][] = $loc_val;
}
$final_json[$counter]['ages'][] = $age_val;
}
$final_json[$counter]['id'] = $course['id'];
$final_json[$counter]['name'] = $cou_val;
$counter++;
}
}
}
}
}
The resulted array should be something like this:
[courses] => array
(
[0] => array
(
[name] => "course_1",
[ages] => array
(
[0] => array
(
[age] => 16,
[locations] => array ([0]=>"Berlin",[1]=>"London")
),
[1] => array
(
[age] => 18,
[locations] => array ([0]=>"Berlin",[1]=>"Rome")
),
[2] => array
(
[age] => 20,
[locations] => array ([0]=>"Berlin")
)
)
)
[1] => array
(
[name] => "course_2",
[ages] => array
(
[0] => array
(
[age] => 16,
[locations] => array ([0]=>"Berlin")
)
)
)
);
I'm fighting with this for some time, I feel blocked, any idea is more than welcomed.
$courses = array(
array("id"=>1,"name"=>"course_1","age"=>16,"location"=>"Berlin"),
array("id"=>2,"name"=>"course_1","age"=>18,"location"=>"Berlin"),
array("id"=>3,"name"=>"course_1","age"=>20,"location"=>"Berlin"),
array("id"=>4,"name"=>"course_1","age"=>16,"location"=>"London"),
array("id"=>5,"name"=>"course_1","age"=>18,"location"=>"Rome"),
array("id"=>6,"name"=>"course_2","age"=>16,"location"=>"Berlin"),
);
foreach ($courses as $item) {
$course_age[] = $item['age'];
$course_names[] = $item['name'];
$course_location[] = $item['location'];
}
$course_age = array_unique($course_age);
$course_names = array_unique($course_names);
$course_location = array_unique($course_location);
$finalArray = array();
$finalArrayKey=0;
foreach ($course_names as $key => $courseValue) {
foreach ($courses as $key => $actualValue) {
if($actualValue['name']==$courseValue){
$finalArray[$finalArrayKey]['name'] = $courseValue;
$finalArray[$finalArrayKey]['ages'] = array();
$finalArray[$finalArrayKey]['ages']['location'] = array();
}
}
foreach ($courses as $key => $actualValue) {
if($actualValue['name']==$courseValue){
if(!in_array($actualValue['age'], $finalArray[$finalArrayKey]['ages']))
$finalArray[$finalArrayKey]['ages'][] = $actualValue['age'];
if(!in_array($actualValue['location'], $finalArray[$finalArrayKey]['ages']['location']))
$finalArray[$finalArrayKey]['ages']['location'][] = $actualValue['location'];
}
}
++$finalArrayKey;
}
echo "<pre>";
print_r($finalArray);
Sample Output:
Array
(
[0] => Array
(
[name] => course_1
[ages] => Array
(
[location] => Array
(
[0] => Berlin
[1] => London
[2] => Rome
)
[0] => 16
[1] => 18
[2] => 20
)
)
[1] => Array
(
[name] => course_2
[ages] => Array
(
[location] => Array
(
[0] => Berlin
)
[0] => 16
)
)
)
For simplicity sake decided to modify the output of the finalArray.
The new finalArray would look like this:
Array
(
[course_1] => Array
(
[ages] => Array
(
[16] => Array
(
[locations] => Array
(
[0] => Berlin
[1] => London
)
),
[18] => Array
(
[locations] => Array
(
[0] => Berlin
[1] => Rome
)
),
[20] => Array
(
[locations] => Array
(
[0] => Berlin
)
)
)
),
[course_2] => Array
(
[ages] => Array
(
[16] => Array
(
[locations] => Array
(
[0] => Berlin
)
)
)
)
)
This is the code:
foreach ($courses as $item) {
$course_names[] = $item['name'];
}
$course_names = array_unique($course_names);
sort($course_names);
$finalArray = array();
foreach ($course_names as $key => $courseValue) {
foreach ($courses as $key => $actualValue) {
if($actualValue['name']==$courseValue) {
$finalArray[$courseValue] = array();
$finalArray[$courseValue]['id'] = $actualValue['id'];
$finalArray[$courseValue]['ages'] = array();
}
}
foreach ($courses as $key => $actualValue) {
if($actualValue['name']==$courseValue) {
if(!array_key_exists($actualValue['age'],$finalArray[$courseValue]['ages'])) {
$finalArray[$courseValue]['ages'][$actualValue['age']] = array ();
}
}
}
}
foreach ($finalArray as $course_name=>$arr) {
foreach ($arr['ages'] as $age=>$arr2) {
foreach($courses as $item) {
if($item['name'] == $course_name && $item['age'] == $age && !in_array($item['location'], $finalArray[$course_name]['ages'][$age]['locations'])) {
$finalArray[$course_name]['ages'][$age]['locations'][] = $item['location'];
}
}
}
}
Not sure exactly what format you're looking for, but have a look at this:
$courses = array
(
array('id'=>1, 'name' =>"course_1",'age'=>16,'location'=>"Berlin"),
array('id'=>2,'name'=>"course_1",'age'=>18,'location'=>"Berlin"),
array('id'=>3,'name'=>"course_1",'age'=>20,'location'=>"Berlin"),
array('id'=>4,'name'=>"course_1",'age'=>16,'location'=>"London"),
array('id'=>5,'name'=>"course_1",'age'=>18,'location'=>"Rome"),
array('id'=>6,'name'=>"course_2",'age'=>16,'location'=>"Berlin")
);
$newCourses = [];
foreach ($courses as $item){
$newCourses[$item['name']]['ages'][$item['age']]['locations'][] = $item['location'];
}
$newCourses will be:
array (
'course_1' =>
array (
'ages' =>
array (
16 =>
array (
'locations' =>
array (
0 => 'Berlin',
1 => 'London',
),
),
18 =>
array (
'locations' =>
array (
0 => 'Berlin',
1 => 'Rome',
),
),
20 =>
array (
'locations' =>
array (
0 => 'Berlin',
),
),
),
),
'course_2' =>
array (
'ages' =>
array (
16 =>
array (
'locations' =>
array (
0 => 'Berlin',
),
),
),
),
)
Even if this isn't the format you're after you could probably play with it to get it how you want.

Flatten multidimensional array PHP

I need to flatten a PHP array but having some issues getting the desired results.
Array
(
[0] => Array
(
[case_code_id] => 1
[parent_id] => 0
[case_code] => Main A
[sub_codes] => Array
(
[0] => Array
(
[case_code_id] => 3
[parent_id] => 1
[case_code] => Sub A
[sub_codes] => Array
(
[0] => Array
(
[case_code_id] => 5
[parent_id] => 3
[case_code] => Sub Sub A
[sub_codes] => Array
(
)
)
)
)
[1] => Array
(
[case_code_id] => 4
[parent_id] => 1
[case_code] => Sub B
[sub_codes] => Array
(
)
)
)
)
[1] => Array
(
[case_code_id] => 2
[parent_id] => 0
[case_code] => Main B
[sub_codes] => Array
(
)
)
)
But I would like to convert this to the following:
Array
(
[0] => Array
(
[case_code_id] => 1
[parent_id] => 0
[case_code] => Main A
)
[1] => Array
(
[case_code_id] => 3
[parent_id] => 1
[case_code] => Sub A
)
[2] => Array
(
[case_code_id] => 5
[parent_id] => 3
[case_code] => Sub Sub A
)
[3] => Array
(
[case_code_id] => 4
[parent_id] => 1
[case_code] => Sub B
)
[4] => Array
(
[case_code_id] => 2
[parent_id] => 0
[case_code] => Main B
[sub_codes] => Array
)
I have tried several loops but nothing returns the full array.
Here is what I have for my loop:
public function array_flatten($array,$list=array()){
for ($i=0;$i<count($array);$i++) {
$results[] = array(
'case_code_id'=>$array[$i]['case_code_id'],
'case_code'=>$array[$i]['case_code'],
'parent_id'=>$array[$i]['parent_id']
);
if (count($array[$i]['sub_codes']) > 0) {
$this->array_flatten($array[$i]['sub_codes'],$results);
} else {
$results[] = $array[$i];
}
}
return $results;
}
And I'm calling it like this: ($multi contains the multidimensional array)
$flat = $this->array_flatten($multi);
The variable $multi is created from this function:
public function build_case_code_tree(array $elements, $parentId = 0) {
$branch = array();
foreach ($elements as $element) {
if ($element['parent_id'] == $parentId) {
$children = $this->build_case_code_tree($elements, $element['case_code_id']);
$element['sub_codes'] = $children;
$branch[] = $element;
}
}
return $branch;
}
Any thoughts?
function array_flatten($a, $flat = []) {
$entry = [];
foreach ($a as $key => $el) {
if (is_array($el)) {
$flat = array_flatten($el, $flat);
} else {
$entry[$key] = $el;
}
}
if (!empty($entry)) {
$flat[] = $entry;
}
return $flat;
}
print_r(array_flatten($multi));
You're not using $list anywhere in the code, and nothing is passed by reference.
You're close, but your function should use $list in the place of $results, and it should receive $list by reference and modifying it in place instead of returning it.
Something like this (untested though):
function array_flatten($array,&$list=array()){
for ($i=0;$i<count($array);$i++) {
$list[] = array(
'case_code_id'=>$array[$i]['case_code_id'],
'case_code'=>$array[$i]['case_code'],
'parent_id'=>$array[$i]['parent_id']
);
if (count($array[$i]['sub_codes']) > 0) {
$this->array_flatten($array[$i]['sub_codes'],$list);
} else {
$list[] = $array[$i];
}
}
}
And calling it like this:
$flat = Array();
$this->array_flatten($multi, $flat);
// Result is inside $flat now

multidimensional array store each list array inside another array

I have nested multidimensional arrays that may be 2 or 3 levels deep. Inside it I may or may not have list arrray. I need to loop over the array:
Array
(
[0] => Array
(
[id] => 1
[name] => cat_name_1
[list] => Array
(
[1] => swgdgbdg
[2] => xcbcxb
)
)
[1] => Array
(
[id] => 3
[name] => cat_name_3
[list] => Array
(
[0] => Array
(
[id] => 1
[name] => cat_name_1
[list] => Array
(
[1] => 543h54h
[2] => 54hrhhfr2
)
)
[1] => Array
(
[id] => 2
[name] => cat_name_2
[list] => Array
(
[1] => eherfherh
[2] => 4564642
)
)
[2] => Array
(
[1] => erggb45yt
[2] => jyuk768k
)
[3] => Array
(
[1] => sdgsdgsdg
[2] => 4tg34g34g
)
)
)
and store the following in another array:
array (
0 => array (
[1] => swgdgbdg
[2] => xcbcxb
) ,
1 => array(
[1] => 543h54h
[2] => 54hrhhfr2
) ,
2 => array(
[1] => eherfherh
[2] => 4564642
),
3 => array(
[1] => erggb45yt
[2] => jyuk768k
),
4 => array(
[1] => sdgsdgsdg
[2] => 4tg34g34g
)
);
You can use array_walk_recursive() to get the key 1,2 and are not array element, like this, check the live demo here.
$result = [];
$temp = [];
array_walk_recursive($array, function($v, $k) use(&$result, &$temp){
if($k == 1)
$temp[$k] = $v;
if($k == 2)
{
$temp[$k] = $v;
$result[] = $temp;
}
});
print_r($result);
Edit for unfixed length and unordered index, live demo.
Extend the array_walk_recursive() with a third parameter for the callfunction to indicate if it's at the start of an subarray.
$result = [];
$temp = [];
$length = 0;
uarray_walk_recursive($array, function($v, $k, $f) use(&$result, &$temp, &$length){
if(is_numeric($k)) {
if($f && $length != 0) {
$result[] = $temp;
$length = 0;
$temp = [];
}
$temp[$k] = $v;
$length++;
}
});
$result[] = $temp;
print_r($result);
function uarray_walk_recursive(&$input, $funcname)
{
if (!is_callable($funcname)) {
if (is_array($funcname)) {
$funcname = $funcname[0] . '::' . $funcname[1];
}
user_error('uarray_walk_recursive() Not a valid callback ' . $user_func,
E_USER_WARNING);
return;
}
if (!is_array($input)) {
user_error('uarray_walk_recursive() The argument should be an array',
E_USER_WARNING);
return;
}
$args = func_get_args();
$flag = true;
foreach ($input as $key => $item) {
if (is_array($item)) {
$args[2] = false;
$flag = true;
uarray_walk_recursive($item, $funcname, $args);
$input[$key] = $item;
} else {
$args[2] = $flag;
$flag = false;
$args[0] = &$item;
$args[1] = &$key;
call_user_func_array($funcname, $args);
$input[$key] = $item;
}
}
}
PseudoCode
function getSomething(var arr)
{
flag = 0;
output = []
for( i = 0 to arr.length)
{
check arr[i] is array,
if yes,then flag = 1 and output.add(getSomething(arr[i]))
if not, continue
}
if flag =0,then return arr
else return output;
}

Parse array to get required data

I have an input array like this:
Array
(
[one] => one
[two] => two
[group1] => Array
(
[three] => three
[four] => four
[group2] => Array
(
[five] => five
)
)
[group3] => Array
(
[six] => six
)
)
I want to extract following 6 strings from above array:
Array
(
[0] => one
[1] => two
[2] => group1,three
[3] => group1,four
[4] => group1,group2,five
[5] => group3,six
)
Any Idea? Is there any useful PHP function for this?
I have tried something like this:
function getStrings( $data, &$result, $parent = '' ) {
foreach( $data as $key => $value ) {
if( is_array( $value ) ) {
getStrings( $value, $result, $key );
} else {
if( $parent == '' ) {
$result[] = $value;
} else {
$result[] = $parent . ',' . $value;
}
}
}
}
$tree = array();
getStrings( $input, $tree );
print_r( $tree );
Result:
Array
(
[0] => one
[1] => two
[2] => group1,three
[3] => group1,four
[4] => group2,five
[5] => group3,six
)
According to your data structure which is:
$data = [
'one' => 'one',
'two' => 'two',
'group1' => [
'three' => 'three',
'four' => 'four',
'group2' => ['five']
],
'group3' => ['six' => 'six']
];
You can use Recursive function:
function make_implode($data){
$rows = [];
foreach($data as $key => $val) {
if(is_array($val)) {
//$rows[] = $key;
$nestedData = make_implode($val);
if(is_array($nestedData)){
foreach($nestedData as $keyNested => $valNested) {
$rows[] = $key.','.$valNested;
}
} else {
$rows[] = $key.','.$nestedData;
}
} else {
$rows[] = $val;
}
}
return $rows;
}
$data = make_implode($data);
echo '<pre>'.print_r($data,1).'</pre>';
//prints
Array
(
[0] => one
[1] => two
[2] => group1,three
[3] => group1,four
[4] => group1,group2,five
[5] => group3,six
)
use a recursive function, similar to:
$a = array("one"=>"one","group1"=>array("three"=>"three"));
var_dump($a);
function recFor($a) {
foreach($a as $k => $v) {
if(is_array($v)) {
$tmp= recFor($v);
$res[] = $tmp[0];
} else {
$res[] = $v;
}
}
return $res;
}
$b = recFor($a);
var_dump($b);
This is just a quick and dirty example, but you should get the idea.

PHP - merging 2D array by keys

How can I merge these array together?
Array
(
[0] => Array
(
[type] => Person
[relevance] => 0.700000
[count] => 300
[text] => Chris
)
)
Array
(
[0] => Array
(
[type] => Person
[relevance] => 0.900000
[count] => 400
[text] => Chris
)
[1] => Array
(
[type] => Person
[relevance] => 0.500000
[count] => 200
[text] => Tom
)
)
or array like this:
Array
(
[0] => Array
(
[type] => Person
[relevance] => 0.700000
[count] => 300
[text] => Chris
)
[1] => Array
(
[type] => Person
[relevance] => 0.900000
[count] => 400
[text] => Chris
)
[2] => Array
(
[type] => Person
[relevance] => 0.500000
[count] => 200
[text] => Tom
)
)
The expected result is:
Array
(
[0] => Array
(
[type] => Person
[relevance] => 0.800000
[count] => 700
[text] => Chris
)
[1] => Array
(
[type] => Person
[relevance] => 0.500000
[count] => 200
[text] => Tom
)
)
[relevance] value is an average number
[count] value is an incremental number
The merging of these array should base on [text] value.
How can I do this with php in a fast way?
Thanks for helping.
If this is the array
$array = Array(
Array(
'type' => 'Person',
'relevance' => .7,
'count' => 300,
'text' => 'Chris'
),
Array(
'type' => 'Person',
'relevance' => .9,
'count' => 400,
'text' => 'Chris'
),
Array(
'type' => 'Person',
'relevance' => .5,
'count' => 200,
'text' => 'Tom'
),
);
then:
$tmp = Array();
foreach($array as $obj) {
if(!isset($tmp[$obj['text']])) {
$tmp[$obj['text']] = array_merge(Array('total_count'=>1),$obj);
continue;
}
$tmp[$obj['text']]['count'] += $obj['count'];
$tmp[$obj['text']]['relevance'] += $obj['relevance'];
$tmp[$obj['text']]['total_count']++; // useful for average calculation
}
$result = Array();
foreach($tmp as $key=>$obj) {
$obj['relevance'] = $obj['relevance']/$obj['total_count'];
unset($obj['total_count']); // useless now
$result[] = $obj;
}
print_r($result);
Something like this maybe:
$newArray = array();
foreach ($oldArray as $item) {
if (!array_key_exists($item['text'], $newArray)) {
$newArray[$item['text']] = $item;
$newArray[$item['relevance_values']] = array();
} else {
$newArray[$item['text']]['count'] += $item['count'];
$newArray[$item['relevance_values']][] = $item['relevance'];
}
}
foreach ($newArray as $item) {
$relevance = 0;
foreach ($item['relevance_values'] as $value) {
$relevance += $value;
}
$item['relevance'] = $relevance / count($item['relevance_values']);
}
Try this:
function mergeOnText($array){
$results = array();
foreach($array as $person){
$found = -1;
foreach($results as $i => $res)
if($res['text'] == $person['text']){
$found = $i;
break;
}
if($found > -1){
$results[$found]['relevance'][] = $person['relevance'];
$results[$found]['count'] += $person['count'];
} else {
$results[] = $person;
}
}
foreach($results as $i => $res)
$results[$i]['relevance'] = array_sum($res['relevance']) / count($res['relevance']);
return $results;
}

Categories