1

I have following task to do, if there is any chance I would appreciate some help to make it in as efficient way as possible. I need to compare values from array of objects (which comes from Laravel Query Builder join query) with array values.

Objects consist of database stored values:

0 => array:2 [
  0 => {#912
    +"addition_id": 1
    +"valid_from": "2015-09-13 00:00:00"
    +"valid_to": "2015-09-19 00:00:00"
    +"price": "0.00"
    +"mode": 0
    +"alias": "Breakfast"
  }
  1 => {#911
    +"addition_id": 2
    +"valid_from": "2015-09-13 00:00:00"
    +"valid_to": "2015-09-19 00:00:00"
    +"price": "10.00"
    +"mode": 1
    +"alias": "Dinner"
  }

while array includes new data, being processed by my method.

0 => array:3 [
  0 => array:6 [
    "id" => 1
    "alias" => "Breakfast"
    "price" => "0.00"
    "mode" => 0
    "created_at" => "2015-09-12 21:25:03"
    "updated_at" => "2015-09-12 21:25:03"
  ]
  1 => array:6 [
    "id" => 2
    "alias" => "Dinner"
    "price" => "10.00"
    "mode" => 1
    "created_at" => "2015-09-12 21:25:18"
    "updated_at" => "2015-09-12 21:25:18"
  ]
  2 => array:6 [
    "id" => 3
    "alias" => "Sauna Access"
    "price" => "50.00"
    "mode" => 0
    "created_at" => "2015-09-12 21:25:35"
    "updated_at" => "2015-09-12 21:25:35"
  ]
 ]

Now, what I need to do is to find out what position of the array was not in the object (compare id with addition_id) and return it.

Is there any way to do it without two nested foreach loops? I think it can be done somehow smart with array_filter, but I'm not really sure how to write efficient callback (beginner here).

The only way I could get around this was:

private function compareAdditions(array $old,array $new)
{
    $difference = $new;

    foreach($new as $key => $value) {
        foreach($old as $oldEntry) {
            if($oldEntry->addition_id == $value['id']) {
                unset($difference[$key]);
            }
        }
    }

    return $difference;
}

But I would really like to make it without two foreach loops. Help will be very appreciated :)

3
  • what have you tried so far ? Before trying to do something fast, you should try something that work Commented Sep 14, 2015 at 9:31
  • I've updated question with method I've tried and worked. i didn't try any array_filter callback because I'm just learning how they work, I though that maybe stackoverflow will help me with that. Commented Sep 14, 2015 at 9:57
  • You can use array_diff_assoc() Commented Sep 14, 2015 at 9:59

1 Answer 1

1

This might be overkill but it uses a function i write in every project, precisely for these kind of situations :

function additionals($original, $additions) {
    $nonExisiting = [];
    //convert all the objects in arrays
    $additions = json_decode(json_encode($additions), true);
    //create an index
    $index = hashtable2list($original, 'id');
    for(reset($additions); current($additions); next($additions)) {
        $pos = array_search(current($additions)['addition_id'], $index);
        if($pos !== false) {
            //We could replace the originals with the additions in the same loop and save resources
            //$original[$pos] = current($additions);
        } else {
            $nonExisiting[] = current($additions);
        }
    }
    return $nonExisiting;
}

function hashtable2list( $hashtable, $key ){
    $array = [];
    foreach($hashtable as $entry) {
        if( is_array($entry) && isset($entry[$key])) {
            $array[] = $entry[$key];
        } elseif( is_object($entry) && isset($entry->$key)  ) {
            $array[] = $entry->$key;
        } else {
            $array[] = null;
        }
    }
    return $array;
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

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.