简体   繁体   中英

PHP: Create a number of Json arrays from a Json Array based on the group on one key

I have an JSON Array like following:-

[{
    "order_no": "1",
    "contract_no": "DCI-92700028",
    "dc_in_date": "2017-11-06",

}, {
    "order_no": "1",
    "contract_no": "DCI-92700028",
    "dc_in_date": "2017-11-06",

}, {
    "order_no": "G1049",
    "contract_no": "DCI-37500029",
    "dc_in_date": "2017-11-06",

}]

I want to create Number of arrays which will consist all key-value pair of similar contract_no. For above Example, I want output Like:-

Array -I

[{
    "order_no": "1",
    "contract_no": "DCI-92700028",
    "dc_in_date": "2017-11-06",

}, {
    "order_no": "1",
    "contract_no": "DCI-92700028",
    "dc_in_date": "2017-11-06",

}]

and

Array- II

[ {
    "order_no": "G1049",
    "contract_no": "DCI-37500029",
    "dc_in_date": "2017-11-06",

}]

Basic Idea is I have Mysql table which has two column. One is "contract_no" other one is "order_details". I want to update value of order_details as Array-I and Array-II where contract number match.

Is there a way to do this?

Convert the JSON to a php array

/* use json_decode(..., true) for creating an array, not an object of StdClass */
$array = json_decode($json, true);

Then create a temproary (or not temprary) array which contains all the contract_no and add the contents of each array element if the contract_no is the same

$temp_array = array();
foreach($array as $a){
    if(!isset($temp_array[$a['contract_no']])){
        $temp_array[$a['contract_no']] = array($a);
    }
    else{
        array_push($temp_array[$a['contract_no']], $a);
    }
}

This code assumes that all elements of the $array are arrays and all elements of the $array s elements have the contract_no index. If this is not the case you can just use isset to check if the indices exist.

If you do not want the associative array you can just use

$result = array_values($temp_array)

So the $result array (or the $temp_array ) are the Array-I and Array-II of your example stored in one array. I think this is easier. If you still want to have separate arrays (which i would not recommend) you can do something like this:

$array_counter = 1;
foreach($result as $r){
    $array_name = "array".$array_counter;
    $$array_name = $r;
    $array_counter++;
}

Edit

Even though this is the exact same code try this (I added some more error checking):

$temp_array = array();
foreach($array as $a){
    if(isset($a['contract_no']) && !empty($a['contract_no'])){
        if(!isset($temp_array[$a['contract_no']]) || !is_array($temp_array[$a['contract_no']])){
            $temp_array[$a['contract_no']] = array();
        }

        array_push($temp_array[$a['contract_no']], $a);
    }
}

It seems like you are setting the $temp_array[$a['contract_no']] = $a , this would cause the wrong format you are posting. The changed lines of code should make sure that the $a is added to an empty array (even though the code before worked for me and is like I said practicly the same)

This example can be seen in php sandbox here .

you can use array_search and array_column methods.

<?php

function recursive_array_search($needle,$haystack) {
    $return = null;
    foreach($haystack as $key=>$value) {
        $current_key=$key;
        if($needle===$value || (is_array($value) && recursive_array_search($needle,$value) !== null)) {
            $return[] = $current_key;
        }
    }
    return $return;
}

$json = '[{
    "order_no": "1",
    "contract_no": "DCI-92700028",
    "dc_in_date": "2017-11-06"
}, {
    "order_no": "1",
    "contract_no": "DCI-92700028",
    "dc_in_date": "2017-11-06"
}, {
    "order_no": "G1049",
    "contract_no": "DCI-37500029",
    "dc_in_date": "2017-11-06"
}]';
$array = json_decode($json, true);
echo '<pre>';
    print_r($array);
    echo '</pre>';
$columns = array_column($array,'contract_no');
foreach($columns as $column){
    echo 'Contact No:'.$column.'<br />';
    $found_key = recursive_array_search($column, $array);
    echo '<pre>';
    print_r($found_key);
    echo '</pre>';

}
?>

You can use functions on arrays (array_map and array_filter) in order to get the result.

First, you need to find the list of contracts numbers (the key of the search).

Then for each contract number, you need to construct an array of records matching the key.

<?php

$json = <<< END
[{
    "order_no": "1",
    "contract_no": "DCI-92700028",
    "dc_in_date": "2017-11-06"
}, {
    "order_no": "1",
    "contract_no": "DCI-92700028",
    "dc_in_date": "2017-11-06"
}, {
    "order_no": "G1049",
    "contract_no": "DCI-37500029",
    "dc_in_date": "2017-11-06"
}]
END;

$a = json_decode($json,true);

// list of $contract_no
$contracts = array_unique( // remove duplicates values
    array_map( // applies the callback to the elements of $a
        function ($item) { // return the contract_no of each record of $a
            return $item['contract_no'];
        }, $a)
);

$result = [];
foreach( $contracts as $contract_no ) {
    $result[] = array_filter($a, // filters records of $a  using a callback function
        function ($item) use ($contract_no) { // anonymous function inherit of $contract_no
            if ($item['contract_no'] === $contract_no) {
                return $item; // return record of $a if the test is true
            }
        }
    );
}

var_dump($result);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM