在PHP中按数组键的值对字典中的数组进行排序

Posted

技术标签:

【中文标题】在PHP中按数组键的值对字典中的数组进行排序【英文标题】:Sorting an array within a dictionary by the array key's value in PHP 【发布时间】:2014-03-21 21:34:34 【问题描述】:

这是一个由两部分组成的问题,但下面是我的 php 代码,我想按天按升序(0,1,...6)对 business_hours 进行排序。这在 PHP 或 ios 中更容易吗(这是为集成到 iOS 应用程序而编写的)?

另外,旁注,我的 iOS 开发人员说他在返回如下所示的位置数组字典时遇到了问题。他宁愿将位置作为编号数组(JSON for [,,...] 而不是我所拥有的 ,,...),但问题是我根本做不到在 PHP 中找到一种方法来满足此应用程序的要求。我特别需要使用数组键将营业时间添加到其相应的位置。我正在连接三个表以获取营业时间和位置 ID,以便营业时间的位置 ID 与位置本身的位置 ID 匹配;这似乎是让两个数组加入以使 JSON 输出数组工作的唯一方法...您可以在下面看到,但如果我错了,或者我的 iOS 开发人员更容易学习,请告诉我如何遍历并返回具有键的多维关联数组的所有数组值。请指教!

if ($stmt = $dbh->prepare($query)) 
            // initialise an array for the results 
            $result = array();
            if ( $stmt->execute(array($lat,$lat,$lng,$rest_price,$eat_in,$take_out,$delivery)) ) 
                        // loop through all values
                while ( $row = $stmt->fetch(PDO::FETCH_ASSOC) ) 
                    // Have we seen this menu before? If not, add it to the array
                    if ( !isset($result['locations'][$row['rest_id']]) ) 
                        $result['locations'][$row['rest_id']] = array(
                            'rest_id' => $row['rest_id'],
                            'user_id' => $row['user_id'],
                            'rest_name' => $row['rest_name'],
                            'lat' => $row['lat'],
                            'lng' => $row['lng'],
                            'rest_price' => $row['rest_price'],
                            'rest_rating' => $row['rest_rating'],
                            'rest_genre' => $row['rest_genre'],
                            'eat_in' => $row['eat_in'],
                            'take_out' => $row['take_out'],
                            'delivery' => $row['delivery'],
                            'rest_img' => $row['rest_img'],
                            'user_img' => $row['user_img'],
                            'business_hours' => array()
                        );
                    
                    // Add the ingredient.
                    // remove all NULL, FALSE and Empty Strings but leave 0 (zero) values
                    $result['locations'][$row['rest_id']]['business_hours'][] = array_filter(array(
                        'day' => $row['day'],
                        'open_time' => $row['open_time'],
                        'close_time' => $row['close_time']
                    ), 'strlen');
                

                // print results if not null
                if( $result != null )        
                    // print success. no error.
                    $result['error'] .= '';     
                    echo json_encode($result);
                    //print_r($result);
                 else 
                    echo json_encode(array('error' => 'No locations exist in your area'));
                

数组

(
[locations] => Array
    (
        [67] => Array
            (
                [rest_id] => 67
                [user_id] => 19
                [rest_name] => The Ninja
                [lat] => 34.1516
                [lng] => -106.685591
                [rest_price] => 2
                [rest_rating] => 3.5
                [rest_genre] => Japanese
                [eat_in] => 1
                [take_out] => 1
                [delivery] => 1
                [rest_img] => 88/image11.png
                [user_img] => image595.png
                [business_hours] => Array
                    (
                        [0] => Array
                            (
                                [day] => 4
                                [open_time] => 09:00:00
                                [close_time] => 16:30:00
                            )

                        [1] => Array
                            (
                                [day] => 1
                                [open_time] => 10:00:00
                                [close_time] => 17:00:00
                            )

                        [2] => Array
                            (
                                [day] => 6
                                [open_time] => 12:00:00
                                [close_time] => 18:00:00
                            )

                        [3] => Array
                            (
                                [day] => 3
                                [open_time] => 10:00:00
                                [close_time] => 17:00:00
                            )

                        [4] => Array
                            (
                                [day] => 0
                                [open_time] => 00:00:00
                                [close_time] => 00:00:00
                            )

                        [5] => Array
                            (
                                [day] => 5
                                [open_time] => 10:00:00
                                [close_time] => 17:00:00
                            )

                        [6] => Array
                            (
                                [day] => 2
                                [open_time] => 10:00:00
                                [close_time] => 17:00:00
                            )

                    )

            )// more arrays occur after this...

    )

[error] => 
)

JSON

"locations":"67":"rest_id":"67","user_id":"19","rest_name":"The Ninja","lat":"","lng":"","rest_price":"2","rest_rating":"3.5","rest_genre":"Japanese","eat_in":"1","take_out":"1","delivery":"1","rest_img":"","user_img":"","business_hours":["day":"6","open_time":"12:00:00","close_time":"18:00:00","day":"3","open_time":"10:00:00","close_time":"17:00:00","day":"0","open_time":"00:00:00","close_time":"00:00:00","day":"5","open_time":"10:00:00","close_time":"17:00:00","day":"2","open_time":"10:00:00","close_time":"17:00:00","day":"4","open_time":"09:00:00","close_time":"16:30:00","day":"1","open_time":"10:00:00","close_time":"17:00:00"],,...,"error":""

【问题讨论】:

贴一个实际的JSON字符串实例,尽量缩短,我来看看。换句话说,我希望看到一个从顶层开始的 JSON 字符串,包括带有 [0] => Array[1] => Array 子条目的 [67] => Array 条目,但没有 [67] 的其他子条目,并且没有所有其余条目 [89]、[99] 等。 完成。希望这提供了任何人都需要看到才能理解的所有结果输出。我想当我的 iOS 开发人员看到一个类似"locations":[,,...],"error":"" 的数组时,我真的很喜欢它,而且我通常使用 PHP 在服务器端完成所有繁重的工作,但是在按数字天排序营业时间时遇到问题,无论我是否需要特定格式的数组(对与错) 【参考方案1】:

嗯,这需要很长时间(部分原因是 json 字符串无效,因为它有一个 ...,但是 w/e)。

您的开发人员更喜欢这样的字典数组 "locations":[,,...],"error":"" 而不是这样的字典字典 "locations":"67":,"89":,... ,"error":"" 因为字典数组非常适合 iOS 表格视图范例。但是,将字典字典转换为字典数组只需一行代码,例如

NSArray *locationAllValues = [locationDictionary allValues];

所以唯一的问题是性能问题。你是强制服务器做更多的工作来生成首选格式,还是让移动设备做一些工作?

解析 JSON 数据时,我建议使用 NSJSONReadingMutableContainers 选项,以便数组和字典是可变的。这样可以更轻松地对 day 数组进行排序。是的,在 iOS 中对数组进行排序很容易。这是从输入 JSON 创建字典数组的完整代码集。代码的输入是一个 NSData 对象,其中包含从网络下载的 JSON 字符串。字典数组按rest_id排序,每个字典内business_hours数组按day排序。

请注意,代码没有错误检查,除了在调用JSONObjectWithData 之后检查nil。这只是概念证明,而不是生产代码。使用风险自负。

- (NSArray *)parseAndSortJsonResponse:(NSData *)data

    NSDictionary *jsonData = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
    if ( !jsonData )
    
        NSLog( @"Invalid JSON string" );
        return( nil );
    

    NSMutableDictionary *locationDictionary = jsonData[@"locations"];
    NSArray *locationAllValues = [locationDictionary allValues];

    NSArray *locationsArray = [locationAllValues sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2)
    
        NSDictionary *d1 = obj1;
        NSDictionary *d2 = obj2;

        int v1 = [d1[@"rest_id"] intValue];
        int v2 = [d2[@"rest_id"] intValue];

        if ( v1 < v2 )
            return( NSOrderedAscending );
        else if ( v1 > v2 )
            return( NSOrderedDescending );
        else
            return( NSOrderedSame );
    ];

    for ( NSMutableDictionary *location in locationsArray )
    
        NSArray *array = location[@"business_hours"];
        NSArray *sorted = [array sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2)
        
            NSDictionary *d1 = obj1;
            NSDictionary *d2 = obj2;

            int v1 = [d1[@"day"] intValue];
            int v2 = [d2[@"day"] intValue];

            if ( v1 < v2 )
                return( NSOrderedAscending );
            else if ( v1 > v2 )
                return( NSOrderedDescending );
            else
                return( NSOrderedSame );
        ];
        [location setObject:sorted forKey:@"business_hours"];
    

    NSLog( @"%@", locationsArray );

    return( locationsArray );

【讨论】:

@jflay 我已经修改了关于字典数组的评论。

以上是关于在PHP中按数组键的值对字典中的数组进行排序的主要内容,如果未能解决你的问题,请参考以下文章

按字典键的值对包含 NSMutableDictionary 的 NSMutableArray 进行排序

按特定键的内部数组的值对PHP二维数组进行排序[重复]

如何按给定键的值对关联数组进行排序并在php中维护键? [复制]

如何在多图中按排序顺序打印键的值

有没有一种简单的方法可以按键值对 plist(字典数组)进行排序?

在Python中按值对嵌套字典进行排序,并按另一个值对余数进行排序