How to combine two get_users() array?

The question:

The $q1 and $q2 are working well individually.

if (!empty($search_term)) {

        $q1 = get_users(array(
            'fields' => 'all',
            'role' => 'contact',
            'search' => '*'.esc_attr( $search_term ).'*',
        ));

        $q2 = get_users(array(
            'fields' => 'all',
            'role' => 'contact',
            'meta_query' => array(
                'relation' => 'OR',
                array(
                    'key'     => 'first_name',
                    'value'   => $search_term,
                    'compare' => 'LIKE'
                ),
                array(
                    'key'     => 'last_name',
                    'value'   => $search_term,
                    'compare' => 'LIKE'
                ),
                array(
                    'key' => 'location',
                    'value' => $search_term ,
                    'compare' => 'LIKE'
                )
            )
        ));

        $all_contacts = array_merge( $q1, $q2 );
        //$all_contacts = $q1;

    }

    $contacts_array = array();

    if (count($all_contacts) > 0 ){
        
        foreach ($all_contacts as $index => $contact) {
            $contacts_array[] = array(
                "id" => $contact->ID,
                "name" => $contact->display_name,
                "email" => $contact->user_email,
                "phone" => $contact->phone_number,
                "country" => $contact->location,
                "website" => $contact->user_url,
            );
        }
    }

    return $contacts_array;

How can I merge them together for results?

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

Edit: to clarify, the answer to

How can I merge them together for results?

Is that you really can’t, not without a lot of custom SQL and using filters. The complexity of going that route far outweighs any perceived benefits and wouldn’t be very future-proof. I’d recommend using the solution below and putting it all into a method that you can call to get what you need.

Original Answer

I tested this locally and was able to get two sets of results – from there, I passed them through a callback in array_filter to remove the duplicate entries:

$q1 = get_users(array(
    'fields' => 'all',
    'role'   => 'contact',
    'search' => '*'.esc_attr( $search_term ).'*',
));

$q2 = get_users(array(
    'fields' => 'all',
    'role'   => 'contact',
    'meta_query' => array(
        'relation' => 'OR',
        array(
            'key'     => 'first_name',
            'value'   => $search_term,
            'compare' => 'LIKE'
        ),
        array(
            'key'     => 'last_name',
            'value'   => $search_term,
            'compare' => 'LIKE'
        ),
        array(
            'key' => 'location',
            'value' => $search_term ,
            'compare' => 'LIKE'
        )
    )
));

$results = array_merge( $q1, $q2 );
$results = array_filter( $results, function( $user ) {
    static $found_users = [];

    if ( in_array( $user->ID, $found_users, true ) ) {
        return false;
    }

    $found_users[] = $user->ID;
    return true;
} );

The static array is persisted over each call to the closure, allowing the code to keep track of which users have already been processed. If a user’s ID is in the $found_users array, we return false which removes the current element from the array.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment