I am doing work where I get data in various formats from various sources. I will end up with something like this:
$dataSource1 = ... ;
$dataSource2 = ... ;
$dataSource3 = ... ;
I need to COMBINE these data sources, all with different field names, into one object, that I can sort according to fields, limit to X number etc.... all for display purposes.
What is the best way to do this? Is there a good php library that does this?
Three possible solutions,
You could always create a database and just use that. (Probably the best thing to do)
Alternatively, you could try attempt to do some polymorphisisng? (cant be made into a verb!)
Finally, you could also include all the other pages into the one you will be displaying from.
(I suggest number 1)
I think the simplest way is using an associative array.
$dataSource1 = ...;
$dataSource2 = ...;
...
$dataSourceN = ...;
$data = array()
$data[0] = $dataSource1;
$data[1] = $dataSource2;
And so on. Just remember that a numeric index array always starts at 0. So the first element would be $data[0].
If you want a more complex bind you can create a multidimensional array. It means you can sort by specific fields. See an example:
$data1 = 'Brazil';
$dataArray = array()
$dataArray[] = array(
'countryId' => 'id',
'countryName' => $data1,
'usersFromThisCountry' => $data1Users
);
Now you can sort $dataArray according to 'countryId','countryName','usersFromThisCountry'.
Related
I have an assoc array looking like this (the data comes from user input, this is just an example)
$startingDate = "2020-10-20";
$daysBetween[] = "2020-10-21", "2020-10-22", "2020-10-23";
$endingDate = "2020-10-24";
$eventDates[ID] => [
"startingDate" => $startingDate,
"daysBetween" => $daysBetween,
"endingDate" => $endingDate,
];
How would I look for a specific startingDate for example if I don't want to loop over every ID. Basically I'm looking for a way to do something like $eventDates[*]["startingDate"]
You can achieve this a few different ways, one being array_filter().
$searchFor = '2020-09-20';
$result = array_filter($eventDates, function($v) use ($searchFor) {
return ($v['startingDate'] ?? null) == $searchFor;
});
This returns the array(s) where you match the $searchFor variable with a column startingDate. If you just want the first one, use $result = array_shift($result); to get the first one.
This approach basically filters out any results where the callback doesn't return true. By including use ($searchFor) the variable becomes visible inside the scope of that function, otherwise it would be undefined within that scope.
Live demo at https://3v4l.org/iaT8k
The questioner states that they are looking for a way to do something like
$eventDates[*]["startingDate"]
The PHP equivalent to this is:
foreach ($eventDates as $id => $eventDate) {
//look at $eventDate["startingDate"] and if it matches the criteria do whatever required
//you know the ID (=$id) so you can save/return/use that if needed.
}
Here is my code:
<?php
//header code to define as json and if $_GET statement...
$JSONArrayA[$variableA] = array('id' => $idA, 'test' => $testVariableA);
$JSONArrayB[$variableB] = array('id' => $idB, 'test' => $testVariableB);
//current code resulting in ["ArrayArray"]
$FinalJSONArray[] = $JSONArrayA . $JSONArrayB;
echo json_encode($FinalJSONArray);
?>
My question: How do I make the array contain two or more arrays? Any help appreciated.
array_merge
$FinalJSONArray = array_merge($JSONArrayA, $JSONArrayB);
Merges the elements of one or more arrays together so that the values
of one are appended to the end of the previous one. It returns the
resulting array.
If you want to instead return an array containing the other two arrays themselves,
use
$FinalJSONArray = array($JSONArrayA, $JSONArrayB);
Try
$FinalJSONArray[] = $JSONArrayA;
$FinalJSONArray[] = $JSONArrayB;
This will reult in 2 sub arrays. If you want them merged use:
$FinalJSONArray[] = $JSONArrayA+$JSONArrayB;
"+" with two arrays unions them (see: http://php.net/manual/en/language.operators.array.php)
Depending on what you want your JSON to look like
$FinalJSONArray = array($JSONArrayA,$JSONArrayB);
I have 2 sets of arrays:
$dates1 = array('9/12','9/13','9/14','9/15','9/16','9/17');
$data1 = array('5','3','7','7','22','18');
// for this dataset, the value on 9/12 is 5
$dates2 = array('9/14','9/15');
$data2 = array('12','1');
As you can see the 2nd dataset has fewer dates, so I need to "autofill" the reset of the array to match the largest dataset.
$dates2 = array('9/12','9/13','9/14','9/15','9/16','9/17');
$data2 = array('','','12','1','','');
There will be more than 2 datasets, so I would have to find the largest dataset, and run a function for each smaller dataset to properly format it.
The function I'd create is the problem for me. Not even sure where to start at this point. Also, I can format the date and data arrays differently (multidimensional arrays?) if for some reason that is better.
You can do this in a pretty straightforward manner using some array functions. Try something like this:
//make an empty array matching your maximum-sized data set
$empty = array_fill_keys($dates1,'');
//for each array you wish to pad, do this:
//make key/value array
$new = array_combine($dates2,$data2);
//merge, overwriting empty keys with data values
$new = array_merge($empty,$new);
//if you want just the data values again
$data2 = array_values($new);
print_r($data2);
It would be pretty easy to turn that into a function or put it into a for loop to operate on your array sets. Turning them into associative arrays of key/value pairs would make them easier to work with too I would think.
If datas are related will be painful to scatter them on several array.
The best solution would be model an object with obvious property names
and use it with related accessor.
From your question I haven't a lot of hint of what data are and then I have to guess a bit:
I pretend you need to keep a daily log on access on a website with downloads. Instead of using dates/data1/data2 array I would model a data structure similar to this:
$log = array(
array('date'=>'2011-09-12','accessCount'=>7,'downloadCount'=>3),
array('date'=>'2011-09-13','accessCount'=>9), /* better downloadsCount=>0 though */
array('date'=>'2011-09-15','accessCount'=>7,'downloadCount'=>3)
...
)
Using this data structure I would model a dayCollection class with methods add,remove,get,set, search with all methods returning a day instance (yes, the remove too) and according signature. The day Class would have the standard getter/setter for every property (you can resolve to magic methods).
Depending on the amount of data you have to manipulate you can opt to maintain into the collection just the object data (serialize on store/unserialize on retrieve) or the whole object.
It is difficult to show you some code as the question is lacking of details on your data model.
If you still want to pad your array than this code would be a good start:
$temp = array($dates, $data1, $data2);
$max = max(array_map('count',$temp));
$result = array_map( function($x) use($max) {
return array_pad($x,$max,0);
}, $temp);
in $result you have your padded arrays. if you want to substitute your arrays do a simple
list($dates, $data1, $data2) = array_map(....
You should use hashmaps instead of arrays to associate each date to a data.
Then, find the largest one, cycle through its keys with a foreach, and test the existence of the same key in the small one.
If it doesn't exist, create it with an empty value.
EDIT with code (for completeness, other answers seem definitely better):
$dates_data1 = array('9/12'=>'5', '9/13'=>'3', '9/14'=>'7' /* continued */);
$dates_data2 = array('9/14'=>'12', '9/15'=>'1');
#cycle through each key (date) of the longest array
foreach($dates_data1 as $key => $value){
#check if the key exists in the smallest and add '' value if it does not
if(!isset( $date_data2[$key] )){ $date_data2[$key]=''; }
}
$post_keys = array_keys($_POST);
$special_keys = array();
for($i=0;$i<count($post_keys);$i++){
if(strpos($post_keys[$i], "special") !== false){
$special_keys[] = $post_keys[$i];
}
}
I have numerous post vars with naming conventions such as special0, special0_time, special0_duration, special1, special1_time etc.... What I want to do is to find out how many main groups there are, so special0, special1 etc... The code I currently have searches all key names that have "special" in it, thus retrieving more than I want.
PHP already builds an array for parameters that uses the array like syntax (e.g. arg[]). See How do I create arrays in a HTML <form>?
Gumbo is correct, however if you still need to perform such a task, regex can help:
if(preg_match('/^(?<key>special[0-9]+)_/ix', $post_keys[$i], $match)){
$special_keys[] = $match['key'];
}
After which you can run array_unique() on $special_keys to get an array of groups.
For easier maintenance try this structure:
$_POST = array(
'special' => array(
array('time'=>, 'duration'=>, ''=>),
array('time'=>, 'duration'=>, ''=>),
array('time'=>, 'duration'=>, ''=>),
),
);
Then you can do stuff like count($_POST['special']) and $_POST['special'][1]['time']
I am taking over a large project, and a lot of nested arrays are defined for option select lists to be used with form_dropdown() and form_multiselect() in Codeigniter. However, these arrays simply have values set and not corresponding keys.
Here's an example:
$lists['roomItems'] = array('Private telephone','Television cable/satellite','Personal furniture/decorations','Computer','Radio');
$lists['busRoute'] = array('Yes','No');
$lists['transport'] = array('Medical appointments','Dental appointments','Dialysis center','Wound care center','Religious services',
'Shopping services');
What I'd like to do is recursively go through $lists and make the keys equivalent to the values. For a single array, I tried foreach($lists['roomItems'] as $key=>value) and tried setting the key equal to the value, but it didn't take.
Can anyone help? I have about 30 items in the $lists array plus other ones that I'd re-use this code, so simply manually changing the pointers isn't really something I'd like to do. Thanks!
mhmmm what about:
$newList = array();
foreach($lists as $k=>$v) $newList[$k] = array_combine($v,$v);
should do the trick