Home > Software design >  Sort array object by value in Laravel
Sort array object by value in Laravel

Time:10-21

I have 3 tables like this:

News Table:

|---------|------------------|
| news_id |    news_title    |
|---------|------------------|
|    1    |     Title 1      |
|---------|------------------|
|    2    |     Title 2      |
|---------|------------------|

Service Table:

|------------|----------------|---------------|
| service_id |  service_code  |  service_name |
|------------|----------------|---------------|
|    1       |      home      |      Home     |
|------------|----------------|---------------|
|    2       |      apartment |     Apartment |
|------------|----------------|---------------|

News Service Table:

|-----------------|----------------|---------------|
| news_service_id |     news_id    |  service_code |
|-----------------|----------------|---------------|
|        1        |        2       |      home     |
|-----------------|----------------|---------------|
|        2        |        2       |     apartment |
|-----------------|----------------|---------------|
|        3        |        1       |     apartment |
|-----------------|----------------|---------------|

I tried to get list form News Table, and get service code list from Service Table for each row in News list through News Service Table. Example:

|---------|------------------|----------------|-----------------|
| news_id |    news_title    | service_code   |  service_name   |
|---------|------------------|----------------|-----------------|
|    1    |     Title 1      |  apartment     |    Apartment    |
|---------|------------------|----------------|-----------------|
|    2    |     Title 2      |apartment, home | Apartment, Home |
|---------|------------------|----------------|-----------------|

Here is my code:

Class NewsTable:

class NewsTable extends Model
{
    protected $table      = "news";
    protected $primaryKey = "news_id";


    public function list(array $search = [])
    {
        return $this->select(
                            "{$this->table}.news_id",
                            "{$this->table}.news_title"
                            )
                    ->get();
    }
}

Class NewsServiceTable:

class NewsServiceTable extends Model
{
    protected $table      = "news_service";
    protected $primaryKey = "news_service_id";


    public function listById($id)
    {
        return $this->select("{$this->table}.service_code", "s.service_name")
                    ->leftJoin("service as s", "s.service_code", "=", "{$this->table}.service_code")
                    ->where("{$this->table}.news_id", $id)
                    ->get()
                    ->toArray();
    }
}

My Controller Class:

class NewsController extends Controller
{
    protected $news;
    protected $newsService;


    public function __construct(NewsTable $news, NewsServiceTable $newsService)
    {
        $this->news    = $news;
        $this->newsService = $newsService;
    }

    public function listAction(Request $request)
    {
        $param = $request->filter;

        $data = $this->news->list();

        foreach ($data as $key => $item) {
            $service = $this->newsService->listById($item->news_id);
            $data[$key]["service"] = $service;
        }

        return $data;
    }
}

Here is my result:

[
    {
        "news_id": 1,
        "news_title": "Title 1"
        "service": [
            {
                "service_code": "apartment",
                "service_name": "Apartment"
            }
        ]
    },
    {
        "news_id": 2,
        "news_title": "Title 2"
        "service": [
            {
                "service_code": "home",
                "service_name": "Home"
            },
            {
                "service_code": "apartment",
                "service_name": "Apartment"
            }
        ]
    }
]

Now, if I pass keyword "home" to my controller and get it to param variable, I want to sort this array object by that value, the object which have "home" value in array service will go up, the other will be go down like this:

[
    {
        "news_id": 2,
        "news_title": "Title 2",
        "service": [
            {
                "service_code": "home",
                "service_name": "Home"
            },
            {
                "service_code": "apartment",
                "service_name": "Apartment"
            }
        ]
    },
    {
        "news_id": 1,
        "news_title": "Title 1",
        "service": [
            {
                "service_code": "apartment",
                "service_name": "Apartment"
            }
        ]
    }
]

But I really don't know how to do this.

I tried to describe clearly my problem for you. Hope you can understand my problem.

Thank you very much!

CodePudding user response:

Try this.

class NewsController extends Controller
{
    protected $news;
    protected $newsService;


    public function __construct(NewsTable $news, NewsServiceTable $newsService)
    {
        $this->news    = $news;
        $this->newsService = $newsService;
    }

    public function listAction(Request $request)
    {
        $param = $request->filter;

        $data = $this->news->list();

        foreach ($data as $key => $item) {
            $service = $this->newsService->listById($item->news_id);
            $data[$key]["service"] = $service;
        }

        $order_data = array();
        $keyword = "home";
        foreach ($data as $key => $item) {
            if(array_search($keyword, array_column($item["service"], 'service_code')) !== false){
                array_unshift($order_data, $item);
            }else{
                $order_data[] = $item;
            }
        }

        return $order_data;
    }
}
  • Related