laravel - PHP best performance to delete duplicate array values

11

In my web application I have a function that is executed more than 100 times in a minute, and I'm trying to find a better performing approach.

public static function removeDuplicateFeeds($id, $feeds, $todo)
{
    $actionsHistory = ActionsHistory::whereAccountId($id)->whereActionName($todo)->get();
    if (!empty($actionsHistory)) {
        foreach ($actionsHistory as $history) {
            foreach ($feeds as $key => $feed) {
                if ($history->action_name == $feed['pk']) {
                    unset($feeds[$key]);
                }
            }
        }
    }
}

I want to remove all the elements from$feeds that are in$actionsHistory as well.

UPDATE:

in this test code first index of$feeds array as"pk":"7853740779" is stored on my database and after remove duplicate this item should be removed, but i have all of$feeds items into$filteredFeeds too

$userAccountSource = InstagramAccount::with('user', 'schedule')->get();
$feeds = [
    json_decode('{"pk":"7853740779","username":"teachkidss","full_name":"..."}'),
    json_decode('{"pk":"7853740709","username":"teachkidss","full_name":"..."}'),
    json_decode('{"pk":"7853740009","username":"teachkidss","full_name":"..."}')
];

$filteredFeeds = AnalyzeInstagramPageController::removeDuplicateFeeds($userAccountSource[0]->id, $feeds, 'like');

public function removeDuplicateFeeds($id, $feeds, $todo)
{
    $feeds = collect($feeds); // If $feeds is not already a collection
    $actionsHistory = ActionsHistory::whereAccountId($id)
        ->whereActionName($todo)
        ->whereIn('action_name', $feeds->pluck('pk')) // retrieves only duplicate records
        ->select('action_name')  // reducing the select improves performance
        ->get(); // Should return a eloquent collection instance
    if (!empty($actionsHistory)) {
        return $feeds->whereNotIn('pk', $actionsHistory->pluck('action_name'));
    }
    return $feeds;
}
604

Answer

Solution:

Without knowing the number of feed or database records you'll have to test these for performance against your dataset and see if these are more performant.

public static function removeDuplicateFeeds($id, $feeds, $todo)
{
    $feeds = collect($feeds); // If $feeds is not already a collection
    $actionsHistory = ActionsHistory::whereAccountId($id)
        ->whereActionName($todo)
        ->select('action_name')  // reducing the select improves performance
        ->get(); // Should return an eloquent collection instance
    if (!empty($actionsHistory)) {
        return $feeds->whereNotIn('pk', $actionsHistory->pluck('action_name'));
    }
    return $feeds;
}

or if your database query returns significantly more records than you have feeds you could try leveraging mysql's faster query speed instead of using php's slower array_filter/foreach speed.

public static function removeDuplicateFeeds($id, $feeds, $todo)
{
    $feeds = collect($feeds); // If $feeds is not already a collection
    $actionsHistory = ActionsHistory::whereAccountId($id)
        ->whereActionName($todo)
        ->whereIn('action_name', $feeds->pluck('pk')) // retrieves only duplicate records
        ->select('action_name')  // reducing the select improves performance
        ->get(); // Should return a eloquent collection instance
    if (!empty($actionsHistory)) {
        return $feeds->whereNotIn('pk', $actionsHistory->pluck('action_name'));
    }
    return $feeds;
}

If either of these works, it would be good to know how much faster this was for you. Let us know. Good luck.

330

Answer

Solution:

You may tryarray_unique function from PHP. Source.

759

Answer

Solution:

You can use build in laravel unique() function from collection, see more here : https://laravel.com/docs/5.6/collections#method-unique

doing that you cove will maintain clean and elegant.

People are also looking for solutions to the problem: php - Recursion function over multidimensional array

Source

Didn't find the answer?

Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.

Ask a Question

Write quick answer

Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.

Similar questions

Find the answer in similar questions on our website.