Amit Sankhyan
Amit Sankhyan

Reputation: 1

Merge data into consistent 2d structure while iterating separate query result sets

First iteration result array:

[
    ['id' => '25', 'distance' => 0]
]

Second iteration result array:

[
    ['id' => '24', 'distance' => 0],
    ['id' => '27', 'distance' => 0],
    ['id' => '26', 'distance' => 14.568184704048],
]

I am getting this response because there are multiple locations (multiple lat long), so I am getting two different arrays. How can I push all rows into a single array?

Here's my code:

if (
    !empty($saveArray['area'])
    && !empty($saveArray['radius'])
    || !empty($saveArray['event_name_desc'])
    || !empty($saveArray['tags'])
    || !empty($saveArray['start_date'])
    || !empty($saveArray['end_date'])
) {
    $areas = explode('|', $saveArray['area']);
    // $query = $query->where(function($query) use ($areas) {
    foreach ($areas as $are) {
        $query = Event::query();
        $latlng = explode(',', $are);
        $lat = $latlng[0];
        $lng = $latlng[1];
        $radius = $saveArray['radius'];
        $query = $query->selectRaw("id, ( 3959 * acos( cos( radians(?) ) * cos( radians( latitude ) ) * cos( radians( longitude ) - radians(?)) + sin( radians(?) ) * sin( radians( latitude ) ))) AS distance", [$lat, $lng, $lat])
                       ->having("distance", "<", $radius)
                       ->orderBy("distance", 'asc')
                       ->offset(0)
                       ->limit(20);
        if ($saveArray['event_name_desc']) {
            $query = $query->where('event_name', 'like', '%' . $saveArray['event_name_desc'] . '%');
            $query = $query->orWhere('event_description', 'like', '%' . $saveArray['event_name_desc'] . '%');
        }

        if ($saveArray['tags']) {
            $tags = explode(',', $saveArray['tags']);
            $query = $query->where(
                function($query) use ($tags) {
                    foreach($tags as $tag) {
                        $query->orWhere('tags', 'like', "%$tag%");
                    };
                }
            )
            ->inRandomOrder();
        }

        $events = $query->get();
        $event = json_decode(json_encode($events), true);

        $record = [];
        foreach ($event as $ls) {
            $listing['id'] = (string) $ls['id'];
            $record[] = $listing;
        }
        // $oneDimensionalArray = array_map('current', $record);
        print_r($event);
        // $multiplied = $events->map(function ($item, $key) {
        // return $item->id;
        // })->flatten();
        // print_r($multiplied);
    }
}

Upvotes: 0

Views: 50

Answers (1)

mickmackusa
mickmackusa

Reputation: 47992

If you aren't going to adjust your selectRaw() clause to use OR with all of the lat/long pairs, then you can continue making iterated trips to the database (which I don't recommend).

In your current script, $event = json_decode(json_encode($events), true); is an indexed array of associative arrays.

Declare $result as an empty array before entering the parent loop. Then if you don't want to write another loop, use array_push() and unpack the rows using the spread operator.

array_push($result, ...$events);

Otherwise, if you are going to loop over the $events payload, then just push each row directly into the result array: $result[] = $ls; ($ls is the variable name in your existing script).

As a side note, if you ever need to parse a lat-lng string into separate float -type values, sscanf() is more direct than explode() then manual casting. Split and parse a string to create an array of associative arrays

Upvotes: 0

Related Questions