1

I have an array of matches, each match has an ID and an array of users (from 2 to 4), each user is uniquely identified by it's own user_id. Example of the array:

array (size=2)
 0 => 
 array (size=2)
 'id' => int 11268
 'users' => 
 array (size=2)
 0 => 
 array (size=1)
 'user_id' => int 960781
 1 => 
 array (size=1)
 'user_id' => int 960786
 1 => 
 array (size=2)
 'id' => int 11267
 'users' => 
 array (size=2)
 0 => 
 array (size=1)
 'user_id' => int 960783
 1 => 
 array (size=1)
 'user_id' => int 902177

Now I want to add users details to the above array, so I do a query on the DB and I have this: (the row with id=n contains the details of user with user_id=n)

if ($res = $stmt->get_result()) { // it gets user details
 while($row=$res->fetch_assoc()) {
 foreach ($matches as &$match) {
 foreach ($match['users'] as &$user) {
 if($user['user_id']==$row['id']) {
 $user['details']=$row;
 }
 }
 }
 }
}

This is working fine, but it's not the best way, because for each row I walk all the array. Do you have any idea how can I optimize this?

Thanks very much

Michael
6,5115 gold badges33 silver badges54 bronze badges
asked Sep 12, 2015 at 10:24
2
  • 1
    Store user details in another array and if needed - take value from it. Commented Sep 12, 2015 at 10:46
  • It all boils down to when and where to build a lookup table to reduce the "costs" from iterating over the arrays to a (hopefully) cheaper hashtable access. I guess you have to iterate that "matches"-array first to know what user details you have to query? If so, you could build a lookup then and there. Commented Sep 12, 2015 at 10:50

2 Answers 2

1

You can simplify the problem by indexing the user arrays by userid. The code becomes a bit more complex now, but the computational complexity class is lower. If the new solution is really faster depends on the actual sizes of the individual arrays, so you'd have to measure both solutions with real-life-production-data to see what the fastest solution actually is.

<?php
function index_array_by($array, $key) {
 $result = array();
 foreach($array as &$value) {
 $new_key = $value[$key];
 $result[$new_key] = &$value;
 }
 return $result;
}
foreach($matches as &$match) {
 $match['users'] = index_array_by($match['users'], "user_id");
}
if ($res = $stmt->get_result()) { // it gets user details
 while($row=$res->fetch_assoc()) {
 foreach ($matches as &$match) {
 $user_id = $row['id'];
 $match['users'][$user_id]['details'] = $row;
 }
 }
}
?>
answered Sep 12, 2015 at 10:56
Sign up to request clarification or add additional context in comments.

Comments

0

I found this solution that require to scan the array only once, but I guess it uses more memory since I'm saving the rows into an array:

//Save the results in an array to later add to the matches array
 if ($res = $stmt->get_result()) { //second get: it gets user details
 while($row=$res->fetch_assoc()) {
 $rows[$row['id']]=$row;
 }
 }
 mysqli_free_result($res);
 //Add the user details to the matches array
 foreach ($matches as &$match) {
 foreach ($match['users'] as &$user) {
 $user['details']=$rows[$user['user_id']];
 }
 }
answered Sep 12, 2015 at 13:47

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.