I have 2 api end points that load JSON data...
1. subject matter experts
Array
(
[0] => Array
(
[ExpertiseId] => 1
[IndustryId] => 1
[PersonId] => 3
)
...
)
people database
Array
(
[0] => Array
(
[Id] => 1
[Name] => Joe
[Office] => New York
)
....
)
I'd like to pass both functions into an array, specify to merge on [matter.PersonId] => [people.Id] so the returned array would become
Array
(
[0] => Array
(
[ExpertiseId] => 1
[IndustryId] => 1
[PersonId] => 3
[Id] => 1
[Name] => Joe
[Office] => New York
)
...
)
You have to iterate over both arrays and reorganize the data in such a way that merging can happen. In practice that means rekeying the first array by PersonId and the second by Id; this is very easy to do with array_column:
$matter = array_column($matter, null, 'PersonId');
$people = array_column($people, null, 'Id');
At this point only a simple task is left: merging the items (arrays) that share the same key in both $matter and $people.
In a perfect world that would be an one-liner with array_merge_recursive, but that function does not actually merge arrays that have integer keys like these (the ids we used as keys are integers). So a little standard iteration is in order: pick one of the arrays and merge its contents with the other:
foreach ($people as $id => $data) {
// If there's a guarantee that both arrays will definitely have the same
// set of keys (ids) so that $matter[$id] is guaranteed to exist,
// you can also use the simpler: $matter[$id] += $data
$matter[$id] = isset($matter[id]) ? $matter[$id] + $data : $data;
}
...and now $matter has all the data merged together.
Try array_merge()
$newArray = array_merge(first_array, second_array);
Related
If I have an array which looks something like this:
Array
(
[0] => Array
(
[DATA] => Array
(
VALUE1 = 1
VALUE2 = 2
)
)
[1] => Array
(
[DATA] => Array
(
VALUE3 = 3
VALUE4 = 4
)
)
)
And would like to turn it into this:
Array
(
[0] => Array
(
[DATA] => Array
(
VALUE1 = 1
VALUE2 = 2
VALUE3 = 3
VALUE4 = 4
)
)
)
I basically want to merge all the identical keys which are at the same level.
What would be the best route to accomplish this?
Could the array_merge functions be of any use?
I Hope this makes any sort of sense and thanks in advance for any help i can get.
You can use array_merge_recursive to merge all the items in your original array together. And since that function takes a variable number of arguments, making it unwieldy when this number is unknown at compile time, you can use call_user_func_array for extra convenience:
$result = call_user_func_array('array_merge_recursive', $array);
The result will have the "top level" of your input pruned off (logical, since you are merging multiple items into one) but will keep all of the remaining structure.
See it in action.
i want to restructure my array so that it looks better in a json
here is a print_r of my current variable:
Array
(
[0] => Array
(
[item_id] => 2
)
[1] => Array
(
[item_id] => 1
)
[2] => Array
(
[item_id] => 1
)
)
i want to reconstruct it be like this or similar:
EDIT
Array
(
[item_id] = array([0]=>'2',[1]=>'1', [2]=>'1');
)
sorry for my poor english m(_ _)m
i just want the item_id to have multiple values.
The hurdle
You actually can't in any way produce the output that you desire, since the key needs to be unique.
You can't use a key of item_id more than once, every time you try and set it, it will override what was in there last.
Think about it, how do you then look up the item with key of item_id, you can't, because three things would have that same key.
If the only reason is for cosmetics, I'd leave the output as you currently have it, although it may look a little messy in your JSON, it works.
A different approach
The best you can hope, is to get an output of:
'item_id' => array(
2,
1,
1
)
You can do this with the help of the array_map function:
$array = array('item_id' => array_map('current', $array));
This can be accomplished using this code.
$a['item_id'] = array();
foreach($arr as $key=>$val) {
$a['item_id'][] = $val['item_id'];
}
print_r($a);
$array = array('item_id' => array_map('current', $array));
(
[1] => Array
(
[rules_properties_id] => 1
[operator] => >=
[value] => 2
[function] => NumOrdersPlaced
[rules_properties_params] => Array
(
[num_days] => 30
[customer_id] => 5
)
)
[2] => Array
(
[rules_properties_id] => 1
[operator] => >=
[value] => 5
[function] => NumOrdersPlaced
[rules_properties_params] => Array
(
[num_days] => 90
[customer_id] => 5
)
)
[3] => Array
(
[rules_properties_id] => 2
[operator] => >
[value] => 365
[function] => CustAcctAge
[rules_properties_params] => Array
(
[customer_id] => 5
)
)
)
That's the print_r of an array that I'm getting back from my database. I need to find the index number of the sub-array that contains the function called NumOrdersPlaced (the expected result would be 2.) Is the only way to do this by looping through the array and subarrays and comparing (as in this answer)? Or is there a more efficient, elegant (i.e. one-liner) function available that I don't know about?
No, there is no one liner for searching multidimensional arrays in PHP, expect you'll write a function for it yourself and use it as one liner :)
Approaches would be:
Change the data structure to somewhat that is good for search operations. eg xml with xpath
When creating the array from your question, create another array which indexes are the function names, and which values are pointers to the sub arrays of the original array
Use the database for that operations. It's optimized for it
...
When searching for the 'right' way you'll have to find a compromise between performance of search, insert, update, remove operations, memory consumption and ease of usage.
As you asked for a PHP solution, here comes an example how I would do it in PHP using and additional index array: (approach 2. from the list above)
// we need two arrays now:
$data = array();
$index = array();
// imagine you loop through database query results
foreach($db_result as $record) {
// create a copy of $record as the address
// of record will contain the last(!) element agter foreach
$item = $record;
// store pointers to that array in data and index
$data []= &$item;
$index[$item->function] = &$item;
}
// here is your one liner
$found = isset($index['NumOrdersPlaced']) ? $index['NumOrdersPlaced'] : NULL;
// another index seach:
$found = isset($index['CustAcctAge']) ? $index['CustAcctAge'] : NULL;
// note there is no additonal loop. The cost is the
// additional memory for $index
I'm a bit struggling with the associative arrays in associative arrays. Point is that I always have to drill deeper in an array and I just don't get this right.
$array['sections']['items'][] = array (
'ident' => $item->attributes()->ident,
'type' => $questionType,
'title' => $item->attributes()->title,
'objective' => (string) $item->objectives->material->mattext,
'question' => (string) $item->presentation->material->mattext,
'possibilities' => array (
// is this even neccesary to tell an empty array will come here??
//(string) $item->presentation->response_lid->render_choice->flow_label->response_label->attributes()->ident => (string) $item->presentation->response_lid->render_choice->flow_label->response_label->material->mattext
)
);
foreach ($item->presentation->response_lid->render_choice->children() as $flow_label) {
$array['sections']['items']['possibilities'][] = array (
(string) $flow_label->response_label->attributes()->ident => (string) $flow_label->response_label->material->mattext
);
}
So 'possibilities' => array() contains an array and if I put a value in it like the comment illustrates I get what I need. But an array contains multiple values so I am trying to put multiple values on the position $array['sections']['items']['possibilities'][]
But this outputs that the values are stores on a different level.
...
[items] => Array
(
[0] => Array
(
[ident] => SimpleXMLElement Object
(
[0] => QTIEDIT:SCQ:1000015312
)
[type] => SCQ
...
[possibilities] => Array
(
)
)
[possibilities] => Array
(
[0] => Array
(
[1000015317] => 500 bytes
)
[1] => Array
...
What am trying to accomplish is with my foreach code above is the first [possibilities] => Array is containing the information of the second. And of course that the second will disappear.
Your $array['sections']['items'] is an array of items, so you need to specify which item to add the possibilities to:
$array['sections']['items'][$i]['possibilities'][]
Where $i is a counter in your loop.
Right now you are appending the Arrays to [items]. But you want to append them to a child element of [items]:
You do:
$array['sections']['items']['possibilities'][] = ...
But it should be something like:
$array['sections']['items'][0]['possibilities'][] = ...
$array['sections']['items'] is an array of items, and as per the way you populate the possibilities key, each item will have it's own possibilities. So, to access the possibilities of the item that is being looped over, you need to specify which one from $array['sections']['items'] by passing the index as explained in the first answer.
OR
To make things simpler, you can try
Save the item array (RHS of the first =) to a separate variable instead of defining and appending to the main array at the same time.
Set the possibilities of that variable.
Append that variable to the main $array['sections']['items']
I have:
array[{IsChecked: true, SEC: 0, STP: 0},
{IsChecked: ture ,SEC: 0, STP: 1},
{IsChecked: false, SEC: 1 ,STP: 0}]
How to get each SEC where IsCheked value is true?
I am learning php. In spite of so many examples on google, I am still confused about implementing arrays which are two dimensional and three dimensional. Can anyone explain, in simple terms, with an example please?
The easiest example for me was thinking of a SQL table as a multidimensional array.
The table might look like this:
ID | Name | Email
--------------------------
1 | John | john#email.com
2 | Jane | jane#email.com
And the array might look like this:
Array
(
[0] => Array
(
[0] => 1
[1] => John
[2] => john#email.com
)
[1] => Array
(
[0] => 2
[1] => Jane
[2] => jane#email.com
)
)
The table is turned into an array of arrays. Where each row is accessed by the first index and each column by the second index.
So If I wanted to get "Jane" I would use $array[1][1]
An associative array of that same table might look like this:
Array
(
[0] => Array
(
[ID] => 1
[Name] => John
[Email] => john#email.com
)
[1] => Array
(
[ID] => 2
[Name] => Jane
[Email] => jane#email.com
)
)
You would access "Jane" like $array[1]["Name"]
These are arrays which are nested in other arrays. Depending on how deep they are nested determines what dimensional they are.
Here is an example of a 1D and 2D array, respectively.
$arr =
array(
'item1' => 543,
654 => true,
'xas' => 0.54
);
// Accessing $arr[654] (returns true)
$arr2 = array(
array
(
'a' => 54,
'b' => 'Hello'
),
array
(
'itemx' => true,
954 => 'hello'
)
);
// Accessing $arr[0]['b'] (equal to 'Hello')
For a 3D array, you simply add another nested array into one of the 2nd level array items in the 2D array example.
There also is a very simple way to get started with multidimensional arrays.
Simply take a sheet and a pencil and start writing your multidimensional array down on paper first. It will help you a lot in the beginning.
It should look something like this.
ARRAY0 {
key0.0 => "value0.0",
key0.1 => "value0.1",
key0.2 => ARRAY1 {
key1.0 => "value1.0",
key1.1 => ARRAY2 {
key2.0 => "value2.0",
key2.1 => "value2.1",
},
key1.2 => "value1.2",
},
key0.3 => "value0.3",
};
This is just my way of visualizing the arrays you can come up with your own syntax if you want.
An array can have anything in it, from an integer to a string, to a full blown object, to another array.
Any array on its own is called a 1-dimensional array. If you think of it as a row of boxes, then it's a single row. If an array has another array in it then it's a 2-dimensional array: one of its boxes will be a column, adding another dimension.
$users = array() ;
$jim = array('Jim', 'Smith') ;
$users[] = $jim ;
//or in one step
$users = array(array('Jim', 'Smith')) ;
//then to access the first user:
$jim = $users[0];
//and his firstname:
$jimsname = $users[0][0] ;
//or
$jimsname = $jim[0] ;
You can access elements of the array and its nested arrays by indices, but you need to remember which numeric index corresponds to which piece of information. That's where you can use associative arrays, where the numeric indices are replaced by unique descriptive strings:
$users = array() ;
$jim = array(
'firstname' => 'Jim',
'lastname' => 'Smith'
) ;
$users['jim'] = $jim ;
//then to access jim:
$jim = $users['jim'];
//and his firstname:
$jimsname = $users['jim']['firstname'] ;
//or
$jimsname = $jim['firstname'] ;
That's pretty much it. You can see more here and in the manual
try this simply.
$anArray['abc'][1]['qwe']='this is a value';
$anArray['abc']['avs']='another value';
echo $anArray['abc'][1]['qwe'];
echo $anArray['abc']['avs'];
/*
Array is a bit different in PHP. You can think of array elements as single variables ($anArray['abc'][1]['qwe'] or $anArray['abc']['avs']). And you can create them like single variables. This is an addition to conventional arrays. Conventional way is also supported.
But what happens if you write : $anArray['abc']='something else';
$anArray['abc'] is just a string variable from that point. So you cannot (or may not as I didn't test it yet and practically everything is possible) access $anArray['abc'][1]['qwe'] anymore.
So try to think the elements like variables, first ;)
*/