...

View Full Version : Combing Array Elements Across Different Arrays



Shane.Jeffery
12-05-2008, 04:40 PM
Hey there guys.

I am trying to combine two or more arrays based on values that match within those arrays.

Here is an example of the array I am working with:


[5] => Array
(
[id] => 207
[session_id] => 6589
[conference] => 198
[title] => (206) Studies of Threading Successes in Popular PC Games and Engines
[format] => Tutorial
[type] => 3
[overview] => Half-day tutorial, repeated in morning and after lunch. In this follow-up to 2007's popular Threading Games for Performance tutorial, Paul Lindberg and Brad Werth will present detailed case studies of successful threading practices in modern PC games. Each case study will be bookended by an explanation of the theory and a "what if" discussion of alternative approaches and further improvements. In addition to detail on specific games, major PC engines will be covered -- maybe the one you are planning to use in your next game.
[file_name] => o1/vault/gdc08/slides/S6589i3.ppt
[ftp_url] => ftp://cmpmedia.vo.llnwd.net/o1/vault/gdc08/slides/S6589i3.ppt
[http_url] => http://cmpmedia.vo.llnwd.net/o1/vault/gdc08/slides/S6589i3.ppt
[featured] => 0
[free] => 0
[homepage] =>
[image] =>
[speakers] => Array
(
[0] => Array
(
[id] => 285
[cmpevents_id] => 442854
[link] => https://www.cmpevents.com/GD08/a.asp?option=G&V=3&id=442854
[first_name] => Paul
[last_name] => Lindberg
[job_title] => Senior Software Engineer
[company] => Intel
)

[1] => Array
(
[id] => 254
[cmpevents_id] => 550518
[link] => https://www.cmpevents.com/GD08/a.asp?option=G&V=3&id=550518
[first_name] => Brad
[last_name] => Werth
[job_title] => Senior Software Engineer
[company] => Intel
)

)

[sort_by_speaker] => Paul Lindberg
[sort_by_company] => Intel
[tracks] => Array
(
[0] => Array
(
[id] => 23
[name] => Programming
[conference] => 198
)

)

[tracks_display] => Programming
[type_data] => Array
(
[id] => 3
[name] => Slides
[icon_url] => /vault/images/icon_slideshow.gif
)

[rating] => Array
(
[class] => rating nostar
)

)

[6] => Array
(
[id] => 208
[session_id] => 6589
[conference] => 198
[title] => (206) Studies of Threading Successes in Popular PC Games and Engines
[format] => Tutorial
[type] => 3
[overview] => Half-day tutorial, repeated in morning and after lunch. In this follow-up to 2007's popular Threading Games for Performance tutorial, Paul Lindberg and Brad Werth will present detailed case studies of successful threading practices in modern PC games. Each case study will be bookended by an explanation of the theory and a "what if" discussion of alternative approaches and further improvements. In addition to detail on specific games, major PC engines will be covered -- maybe the one you are planning to use in your next game.
[file_name] => o1/vault/gdc08/slides/S6589i4.ppt
[ftp_url] => ftp://cmpmedia.vo.llnwd.net/o1/vault/gdc08/slides/S6589i4.ppt
[http_url] => http://cmpmedia.vo.llnwd.net/o1/vault/gdc08/slides/S6589i4.ppt
[featured] => 0
[free] => 0
[homepage] =>
[image] =>
[speakers] => Array
(
[0] => Array
(
[id] => 285
[cmpevents_id] => 442854
[link] => https://www.cmpevents.com/GD08/a.asp?option=G&V=3&id=442854
[first_name] => Paul
[last_name] => Lindberg
[job_title] => Senior Software Engineer
[company] => Intel
)

[1] => Array
(
[id] => 254
[cmpevents_id] => 550518
[link] => https://www.cmpevents.com/GD08/a.asp?option=G&V=3&id=550518
[first_name] => Brad
[last_name] => Werth
[job_title] => Senior Software Engineer
[company] => Intel
)

)

[sort_by_speaker] => Paul Lindberg
[sort_by_company] => Intel
[tracks] => Array
(
[0] => Array
(
[id] => 23
[name] => Programming
[conference] => 198
)

)

[tracks_display] => Programming
[type_data] => Array
(
[id] => 3
[name] => Slides
[icon_url] => /vault/images/icon_slideshow.gif
)

[rating] => Array
(
[class] => rating nostar
)

)

Alright, so, here is what needs to happen.

If Array #5 and #6 have the the same session_id and type, I need the file_name, ftp_url, and http_url of Array #6 to be appended to Array #5. All of the values within the arrays are the same minus the file_name, ftp_url, and http_url.

Also, please know that their could be 4-5 matching arrays all with the same session_id and type and they would all need to be merged into *1* entry with their respective file_name, ftp_url, and http_url.

Any ideas on how to do this?

djm0219
12-05-2008, 05:41 PM
Sounds like the array_merge_recursive (http://www.php.net/manual/en/function.array-merge-recursive.php) function may be what you're looking for.

mdg583
12-05-2008, 06:02 PM
I was going to write something up, but you are probably better off learning how to do things like this. It is just straightforward programming logic, as far as I can tell.

I would write a function which accepts an array of sessions. Then maybe do a for(i=0;i<count($sessions);i++) to go through the sessions, and for each one, check all sessions before it (j=0;j<i;j++), and if the session_id and type are equal for $session[i] and $session[j], append $session[i][$key] to $session[j][$key] where $key is any one of the session field keys for the field you want merged. Finally, unset $session[i] if a $session[j] is found.

Or you could make the appended fields arrays by either adding $session[i][key] to an array of a $session[j] is found, or converting $session[i][$key] to an array if it isn't.


Another solution could be to have a $result array that you search in for sessions having the same type and id for each of your sessions, adding the sessions if they aren't there or appending the differing fields if they are. This avoids possibly complicated nested for loops.

Edit: actually, it looks like array_merge_recursive does what your looking for. I didn't see that post when I started writing.

Shane.Jeffery
12-05-2008, 06:16 PM
Sounds like the array_merge_recursive (http://www.php.net/manual/en/function.array-merge-recursive.php) function may be what you're looking for.

That is around what I am looking for. However, what happens if I only want to merge certain elements of the arrays recursively?

djm0219
12-05-2008, 06:34 PM
You'd likely need to roll your own then. Merging arrays is designed to create one from many with or without criteria.

Shane.Jeffery
12-05-2008, 06:50 PM
You'd likely need to roll your own then. Merging arrays is designed to create one from many with or without criteria.

I figured as much.

djm0219
12-05-2008, 07:15 PM
It might be simpler to merge the arrays and then remove the things you didn't really want in the resultant array rather than trying to write something to get exactly what you want.

Shane.Jeffery
12-05-2008, 08:44 PM
Alright I got it VERY close to what I want. Just have one issue.



function combineArrays($arrays) {
$newarray = array();
$cnt = count($arrays);
for ($i=0; $i < $cnt; $i++) {
$array = $arrays[$i];

$comparison_found = false;
$exists_in_array = false;

foreach ($arrays as $nextArray) {

foreach($newarray as $storedarray)
{
if(strpos($storedarray['id'], $nextArray['id']))
{
$exists_in_array = true;
}
}

if(!$exists_in_array)
{
if($comparison_found == true)
{
$match_existing_array = end($newarray);
$compared_array = compareArray($match_existing_array, $nextArray);
if($compared_array)
{
$value_holder = array_pop($newarray);
array_push($newarray, $compared_array);
}

}
else
{
$compared_array = compareArray($array, $nextArray);
if (is_array($compared_array))
{
$newarray[] = $compared_array;

$comparison_found = true;
}
else
{
$comparison_found = false;
}
}
}
}

if($comparison_found == false || $exists_in_array == false)
{
$newarray[] = $array;
}

unset($arrays[$i]);
}
return $newarray;
}

function compareArray($array1, $array2) {
if ($array1['session_id'] == $array2['session_id'] && $array1['type'] == $array2['type'] &&
$array1['id'] != $array2['id']) {

$array1['id'] = $array1['id'].", ".$array2['id'];
$array1['file_name'] = $array1['file_name'].", ".$array2['file_name'];
$array1['ftp_url'] = $array1['ftp_url'].", ".$array2['ftp_url'];
$array1['http_url'] = $array1['http_url'].", ".$array2['http_url'];
$array1['rating']['class'] = $array1['rating']['class'].", ".$array2['rating']['class'];

return $array1;
}
return $false;
}

The problem I am having now is that I cannot get the duplicate entries to go away.

Here is what is coming out:




[1] => Array
(
[id] => 180, 179
[session_id] => 6526
[conference] => 198
[title] => (205) Normal Mapping Industry Survey
[format] => Tutorial
[type] => 3
[overview] => This session will provide a broad survey of the methods, tools and process for generating Normal Map Data. Attendees will learn the process for generating high resolution models using such tools as Mudbox and Zbrush, the process for applying the maps in major 3d packages and how these packages work with normal maps, and we'll peak into the other various methods used on projects to generate normal maps without the use of high resolution assets. All materials in the class will be presented by a number of industry leading speakers experienced in the process.
[file_name] => o1/vault/gdc08/slides/S6526i2.pdf, o1/vault/gdc08/slides/S6526i1.pdf
[ftp_url] => ftp://cmpmedia.vo.llnwd.net/o1/vault/gdc08/slides/S6526i2.pdf, ftp://cmpmedia.vo.llnwd.net/o1/vault/gdc08/slides/S6526i1.pdf
[http_url] => http://cmpmedia.vo.llnwd.net/o1/vault/gdc08/slides/S6526i2.pdf, http://cmpmedia.vo.llnwd.net/o1/vault/gdc08/slides/S6526i1.pdf
[featured] => 0
[free] => 0
[homepage] =>
[image] =>
[speakers] => Array
(
[0] => Array
(
[id] => 397
[cmpevents_id] =>
[link] => https://www.cmpevents.com/GD08/a.asp?option=G&V=3&id=586066
[first_name] => Alex
[last_name] => Velasquez
[job_title] =>
[company] => Raven Software
)

[1] => Array
(
[id] => 396
[cmpevents_id] =>
[link] => https://www.cmpevents.com/GD08/a.asp?option=G&V=3&id=581469
[first_name] => Ricardo
[last_name] => Ariza
[job_title] => Character Artist
[company] => Naughty Dog
)

[2] => Array
(
[id] => 395
[cmpevents_id] =>
[link] => https://www.cmpevents.com/GD08/a.asp?option=G&V=3&id=573755
[first_name] => Scott
[last_name] => Spencer
[job_title] => Digital Art Director
[company] => Gentle Giant Studios
)

[3] => Array
(
[id] => 394
[cmpevents_id] =>
[link] => https://www.cmpevents.com/GD08/a.asp?option=G&V=3&id=571079
[first_name] => Gio
[last_name] => Nakpil
[job_title] => Artist
[company] => Freedom of Teach
)

[4] => Array
(
[id] => 393
[cmpevents_id] =>
[link] => https://www.cmpevents.com/GD08/a.asp?option=G&V=3&id=529524
[first_name] => Rich
[last_name] => Diamant
[job_title] => Lead Character Artist
[company] => Naughty Dog, Inc.
)

[5] => Array
(
[id] => 392
[cmpevents_id] =>
[link] => https://www.cmpevents.com/GD08/a.asp?option=G&V=3&id=524514
[first_name] => Adam
[last_name] => Myhill
[job_title] => Lead Technical Artist
[company] => Pandemic Studios
)

[6] => Array
(
[id] => 391
[cmpevents_id] =>
[link] => https://www.cmpevents.com/GD08/a.asp?option=G&V=3&id=265346
[first_name] => Steve
[last_name] => Chapman
[job_title] => Vice President
[company] => Gentle Giant Studios
)

)

[sort_by_speaker] => Alex Velasquez
[sort_by_company] => Raven Software
[tracks] => Array
(
[0] => Array
(
[id] => 21
[name] => Visual Arts
[conference] => 198
)

)

[tracks_display] => Visual Arts
[type_data] => Array
(
[id] => 3
[name] => Slides
[icon_url] => /vault/images/icon_slideshow.gif
)

[rating] => Array
(
[class] => rating nostar, rating nostar
)

)

[2] => Array
(
[id] => 180
[session_id] => 6526
[conference] => 198
[title] => (205) Normal Mapping Industry Survey
[format] => Tutorial
[type] => 3
[overview] => This session will provide a broad survey of the methods, tools and process for generating Normal Map Data. Attendees will learn the process for generating high resolution models using such tools as Mudbox and Zbrush, the process for applying the maps in major 3d packages and how these packages work with normal maps, and we'll peak into the other various methods used on projects to generate normal maps without the use of high resolution assets. All materials in the class will be presented by a number of industry leading speakers experienced in the process.
[file_name] => o1/vault/gdc08/slides/S6526i2.pdf
[ftp_url] => ftp://cmpmedia.vo.llnwd.net/o1/vault/gdc08/slides/S6526i2.pdf
[http_url] => http://cmpmedia.vo.llnwd.net/o1/vault/gdc08/slides/S6526i2.pdf
[featured] => 0
[free] => 0
[homepage] =>
[image] =>
[speakers] => Array
(
[0] => Array
(
[id] => 397
[cmpevents_id] =>
[link] => https://www.cmpevents.com/GD08/a.asp?option=G&V=3&id=586066
[first_name] => Alex
[last_name] => Velasquez
[job_title] =>
[company] => Raven Software
)

[1] => Array
(
[id] => 396
[cmpevents_id] =>
[link] => https://www.cmpevents.com/GD08/a.asp?option=G&V=3&id=581469
[first_name] => Ricardo
[last_name] => Ariza
[job_title] => Character Artist
[company] => Naughty Dog
)

[2] => Array
(
[id] => 395
[cmpevents_id] =>
[link] => https://www.cmpevents.com/GD08/a.asp?option=G&V=3&id=573755
[first_name] => Scott
[last_name] => Spencer
[job_title] => Digital Art Director
[company] => Gentle Giant Studios
)

[3] => Array
(
[id] => 394
[cmpevents_id] =>
[link] => https://www.cmpevents.com/GD08/a.asp?option=G&V=3&id=571079
[first_name] => Gio
[last_name] => Nakpil
[job_title] => Artist
[company] => Freedom of Teach
)

[4] => Array
(
[id] => 393
[cmpevents_id] =>
[link] => https://www.cmpevents.com/GD08/a.asp?option=G&V=3&id=529524
[first_name] => Rich
[last_name] => Diamant
[job_title] => Lead Character Artist
[company] => Naughty Dog, Inc.
)

[5] => Array
(
[id] => 392
[cmpevents_id] =>
[link] => https://www.cmpevents.com/GD08/a.asp?option=G&V=3&id=524514
[first_name] => Adam
[last_name] => Myhill
[job_title] => Lead Technical Artist
[company] => Pandemic Studios
)

[6] => Array
(
[id] => 391
[cmpevents_id] =>
[link] => https://www.cmpevents.com/GD08/a.asp?option=G&V=3&id=265346
[first_name] => Steve
[last_name] => Chapman
[job_title] => Vice President
[company] => Gentle Giant Studios
)

)

[sort_by_speaker] => Alex Velasquez
[sort_by_company] => Raven Software
[tracks] => Array
(
[0] => Array
(
[id] => 21
[name] => Visual Arts
[conference] => 198
)

)

[tracks_display] => Visual Arts
[type_data] => Array
(
[id] => 3
[name] => Slides
[icon_url] => /vault/images/icon_slideshow.gif
)

[rating] => Array
(
[class] => rating nostar
)

)

[3] => Array
(
[id] => 179
[session_id] => 6526
[conference] => 198
[title] => (205) Normal Mapping Industry Survey
[format] => Tutorial
[type] => 3
[overview] => This session will provide a broad survey of the methods, tools and process for generating Normal Map Data. Attendees will learn the process for generating high resolution models using such tools as Mudbox and Zbrush, the process for applying the maps in major 3d packages and how these packages work with normal maps, and we'll peak into the other various methods used on projects to generate normal maps without the use of high resolution assets. All materials in the class will be presented by a number of industry leading speakers experienced in the process.
[file_name] => o1/vault/gdc08/slides/S6526i1.pdf
[ftp_url] => ftp://cmpmedia.vo.llnwd.net/o1/vault/gdc08/slides/S6526i1.pdf
[http_url] => http://cmpmedia.vo.llnwd.net/o1/vault/gdc08/slides/S6526i1.pdf
[featured] => 0
[free] => 0
[homepage] =>
[image] =>
[speakers] => Array
(
[0] => Array
(
[id] => 397
[cmpevents_id] =>
[link] => https://www.cmpevents.com/GD08/a.asp?option=G&V=3&id=586066
[first_name] => Alex
[last_name] => Velasquez
[job_title] =>
[company] => Raven Software
)

[1] => Array
(
[id] => 396
[cmpevents_id] =>
[link] => https://www.cmpevents.com/GD08/a.asp?option=G&V=3&id=581469
[first_name] => Ricardo
[last_name] => Ariza
[job_title] => Character Artist
[company] => Naughty Dog
)

[2] => Array
(
[id] => 395
[cmpevents_id] =>
[link] => https://www.cmpevents.com/GD08/a.asp?option=G&V=3&id=573755
[first_name] => Scott
[last_name] => Spencer
[job_title] => Digital Art Director
[company] => Gentle Giant Studios
)

[3] => Array
(
[id] => 394
[cmpevents_id] =>
[link] => https://www.cmpevents.com/GD08/a.asp?option=G&V=3&id=571079
[first_name] => Gio
[last_name] => Nakpil
[job_title] => Artist
[company] => Freedom of Teach
)

[4] => Array
(
[id] => 393
[cmpevents_id] =>
[link] => https://www.cmpevents.com/GD08/a.asp?option=G&V=3&id=529524
[first_name] => Rich
[last_name] => Diamant
[job_title] => Lead Character Artist
[company] => Naughty Dog, Inc.
)

[5] => Array
(
[id] => 392
[cmpevents_id] =>
[link] => https://www.cmpevents.com/GD08/a.asp?option=G&V=3&id=524514
[first_name] => Adam
[last_name] => Myhill
[job_title] => Lead Technical Artist
[company] => Pandemic Studios
)

[6] => Array
(
[id] => 391
[cmpevents_id] =>
[link] => https://www.cmpevents.com/GD08/a.asp?option=G&V=3&id=265346
[first_name] => Steve
[last_name] => Chapman
[job_title] => Vice President
[company] => Gentle Giant Studios
)

)

[sort_by_speaker] => Alex Velasquez
[sort_by_company] => Raven Software
[tracks] => Array
(
[0] => Array
(
[id] => 21
[name] => Visual Arts
[conference] => 198
)

)

[tracks_display] => Visual Arts
[type_data] => Array
(
[id] => 3
[name] => Slides
[icon_url] => /vault/images/icon_slideshow.gif
)

[rating] => Array
(
[class] => rating nostar
)

)


Now because ID 179 and 180 were already used in Array #2, they should not be getting their own output like shown in Array #3 and Array #4. If the ID 179 and 180 already exist in a previous array, then do not let them create their own arrays.

Any ideas?

dumpfi
12-06-2008, 12:07 PM
Sorry, but the logic of your combineArrays function is rather crude, making it hard to understand and to change.

Here's a more modular approach:
function normalizeConferences($confs)
{
$norm_confs = array();

foreach($confs as $i => $c)
{
$idx = findConferenceIndex($norm_confs, $c);

if($idx >= 0)
{
$norm_confs[$idx] = mergeConferences($norm_confs[$idx], $c);
}
else
{
$norm_confs[] = $c;
}
}
return $norm_confs;
}
function findConferenceIndex($confs, $conf)
{
foreach($confs as $i => $c)
{
if(equalConferences($c, $conf))
{
return $i;
}
}
return -1;
}
function equalConferences($confA, $confB)
{
return ($confA['session_id'] == $confB['session_id'] && $confA['type'] == $confB['type']);
}
function mergeConferences($confA, $confB)
{
if(!in_array($confB['id'], (array) $confA['id']))
{
mergeConferencesRec($confA, $confB, array('id', 'file_name', 'ftp_url', 'http_url', 'rating' => array('class')));
}

return $confA;
}
function mergeConferencesRec(&$confA, $confB, $props)
{
foreach($props as $key => $prop)
{
if(is_array($prop))
{
mergeConferencesRec($confA[$key], $confB[$key], $prop);
}
else
{
$confA[$prop] = mergeConferenceDetail($confA[$prop], $confB[$prop]);
}
}
}
function mergeConferenceDetail($detailA, $detailB)
{
return array_merge((array) $detailA, (array) $detailB);
}The normalizeConferences function corresponds to your combineArrays function, however the properties of entries are merged by array appending rather than string concatenation.

dumpfi

mdg583
12-07-2008, 01:30 AM
Here is another solution. I think pretty similar.




function mergeSessions(array $sessions){
$keys_to_merge = array('file_name', 'ftp_url', 'http_url');
for($i = 0; $i < count($sessions); $i++){
for($j = 0; $j < $i; $j++){
if($sessions[$i]['session_id'] == $sessions[$j]['session_id'] && $sessions[$i]['type'] == $sessions[$j]['type']){
foreach($keys_to_merge as $key){
//assume $sessions[$j][$key] is an array because the foreach below must have been called on $sessions[$j] first
$sessions[$j][$key][] = $sessions[$i][$key];
}
//unset this session if it matched one before it. Will this affect the for loop?
unset($sessions[$i]);
break 2; // to skip the foreach below if this session matches one before it.
}
}
//If we reach here the session did not match any before it. Convert the keys we want merged into arrays.
foreach($keys_to_merge as $key){
$sessions[$i][$key] = array($sessions[$i][$key]);
}
}
return $sessions;
}

Shane.Jeffery
12-08-2008, 04:14 PM
Thank you guys very much for the help. You have no idea how appreciated it is :)

I decided to go with mdg583's approach. I am still running into an issue though.

The code above works until it finds *1* session that matches. Once it finds it match, then it does the proper array generation for that match. After the first match, it does not matter any of the other sessions properly. Each session is getting its own element within the second dimension of the array.

Any ideas

Shane.Jeffery
12-08-2008, 04:17 PM
Nevermind :)

I tried dumpfi's approach and it worked PERFECTLY!

I am going to study this code a bit and figure out where the hell I went wrong.

Thank you guys SO much for your time. Now I know where to come for help :)



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum