0

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?

  • 1
    `Is there a way to do this?` Of course there is. I dont see anything you have tried so far. So, what have you tried so far? – Manuel Mannhardt Nov 07 '17 at 08:20
  • I tried with if else. If contract number match with previous contract number of array then push into a new array else loop will continue to next. But the problem is It creates only one array not equal to number of matching pairs. – shivam gour Nov 07 '17 at 08:23
  • just u check how many object is there in that json array. after your need.. – Rajasimman R Nov 07 '17 at 08:31
  • https://stackoverflow.com/questions/12706359/php-array-group is very similar – apokryfos Nov 07 '17 at 08:31
  • [decode json into php variables](https://stackoverflow.com/q/43822216/6521116) – LF00 Nov 07 '17 at 08:41

3 Answers3

3

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>';

}
?>
sametcilli
  • 121
  • 2
0

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 $arrays 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.

miile7
  • 2,547
  • 3
  • 23
  • 38
  • It helps :) Thanks a lot. – shivam gour Nov 07 '17 at 08:44
  • I am just weak on this point. I am getting some extra stuffs in this :- { "DCI-92700028": { "order_no": "1", "contract_no": "DCI-92700028", "dc_in_date": "2017-11-06", "0": { "order_no": "1", "contract_no": "DCI-92700028", "dc_in_date": "2017-11-06", } }, "DCI-37500029": { "order_no": "G1049", "contract_no": "DCI-37500029", "dc_in_date": "2017-11-06", } } and Further more I want to update the mysql record at the same time. – shivam gour Nov 07 '17 at 08:49
  • @shivamgour Hmm, I don't exactly know where the extra stuff comes from. Maybe your $json is not formatted the way you posted it? [Here is a link](http://sandbox.onlinephpfunctions.com/code/932af0daa94eac0747a629f2b80d6c4848a369c6) to a php sandbox which had the code summarized which i wrote and it works fine For the mysql records we need a *lot* more information about your database structure and what exactly you are trying to do. – miile7 Nov 07 '17 at 09:15
  • Thanks for look into this. I am getting json array like:- { "order_no": "1", "contract_no": "DCI-92700028", "dc_in_date": "2017-11-06", "0": { "order_no": "1", "contract_no": "DCI-92700028", "dc_in_date": "2017-11-06", } } But I want in this format:- [{ "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", }] Rest all things are good for me. – shivam gour Nov 07 '17 at 11:07
  • Can you paste your code in here? I really don't get the mistake. As I pointed out already the code works for me (have a look at the link). It looks like you are setting the `$temp_array[$a['contract_no']]`= $a;` in the first `if` block. Also I updated my solution, maybe this works for you. – miile7 Nov 07 '17 at 11:19
0

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);
Lebr1
  • 31
  • 3