Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Why it is the best practice to store your message or results in the two dimensional array?
I grilled it a lot in my mind but failed to produce an exact answer
The answers which came up to me with lot of grilling are as following :-
To store 2 messages at one time
To have the facility to store large messages
To store the large number of messages
though I am not sure about any one of them I admit it that my problem is not that programming oriented!
It might be best to look at what the PHP docs have to say about arrays first:
An array in PHP is actually an ordered map. A map is a type that
associates values to keys. This type is optimized for several
different uses; it can be treated as an array, list (vector), hash
table (an implementation of a map), dictionary, collection, stack,
queue, and probably more. As array values can be other arrays, trees
and multidimensional arrays are also possible.
As you can see from that definition, php arrays are very flexible and cover a lot of use cases. The particular area you are asking about is the multidimensional(2D) PHP array style. Now take a look at how a creating a 2D array looks:
$blank2DArray = array(array());
It's fairly clear that what you have is simply an array of arrays, ie a 2d Array.
So where 2D arrays are useful are cases where you have data that goes beyond simple key => value usage. A simple example: You have some results from multiple race car drivers and their scores from a race course. Each driver has multiple pieces of information so you need more than just a single key => value stored for each driver. You could make an object with attributes to store with this kind of thing, but you could handle it very quickly and simply with a PHP 2D array like this:
$drivers = array();
$drivers[0] = array('driver_id' => 2, 'course_id' => 5 'score' => 61.6);
$drivers[1] = array('driver_id' => 3, 'course_id' => 4 'score' => 70.8);
$drivers[2] = array('driver_id' => 8, 'course_id' => 2 'score' => 76.8, 'winner' => 1);
Each driver and their data are represented by a new array and each is added with an index(this does not need to be numeric). Notice driver[2] has an attribute winner that the others do not have; this is allowed because PHP allows for jagged arrays, ie not all entries have to be the same size. You can easily access child elements of each array like this:
$drivers[0]['driver_id'] //prints 2
$drivers[1]['course_id'] //prints 4
$drivers[2]['score'] //prints 76.8
PHP arrays are excellent for solving a variety of problems and 2D arrays specifically allow for representing complex data far beyond simple key => value storage. For an in-depth look under the hood at PHP arrays check out this blog post: Link
So to answer your question it may not always be best practice to use a 2D array, it will depend on the problem you are trying to solve. PHP arrays are a swiss army knife and the 2D variety are excellent for solving problems where you need to store variable, complex data elements.
Your question is very broad so I'll cover the two possibilities that come to mind:
1 > You're looking for a way to have PHP access and use multidimensional arrays:
$sData[0] = array("Name" => "T-Rex", "Type" => "dinosaur");
$sData[1] = array("Name" => "Frog", "Type" => "amphibian");
$sData[2] = array("Name" => "Salamander", "Type" => "amphibian);
This will allow you to have multiple rows with multiple sub-rows worth of data inside of them. There's no limit (besides machine memory) as to how many rows deep you can go.
2 > You're trying to figure out how to store that information in the database. In which case you need two tables like such:
Table: types
Structure: id INT(8) autoincrement, typename VARCHAR(65)
Example Data: 0, dinosaur -- 1, amphibian
Table: animals
Structure: id INT(8) autoincrement, type_id INT(8), name VARCHAR(65)
Example Data: 0, 0, T-Rex -- 1, 1, Frog -- 2, 1, Salamander
Related
TL;DR:
I want to use data from a 1-dimensional array of arbitrary size, created by userinput, and fill its values into the appropriate fields of a 2-dimensional array of arbitrary size, created via query from the Database.
I have a webapplication where the user can access the DBs data both in read-mode and write-mode.
The DB records accessible to him are determined by the departments he belongs to.
The records are organized in a DB structure where a coretable contains data visible to ALL departments, while extensiontables referencing the coretable via FK contain data which are only visible to users who belong to the department associated with this extensiontable.
I'm using Lumen/Laravel and its eloquent model to interact with the DB from my Backend, some examplecode for accessing the DB looks like this:
$join = coretable::with($permittedTables)->find(1);
Here, $permittedTables is an array of tablenames, referencing the extensiontables accessible to the user.
The above code then fetches the following result:
{
"id": 1,
"Internal_key": "TESTKEY_1",
"extensiontable_itc": {
"description": "EXTENSION_iTC_1"
},
"extensiontable_sysops": {
"description": "EXTENSION_SYSOPS_1"
}
}
Now, the user will have a list-like view in the front-end where all this data has been merged into a big table. In this list, the user can click a field and change its value, then send an http-request to persist these changes to the DB.
This http-request will be an array in JSON format, which i will json_decode() in my backend, and use the transmitted id to fetch the model as seen above.
Now, at this point, two sets of data, organized in the structure of associative arrays, will face each other. The input from the http-request will likely be a 1-dimensional array, while the model from the DB will almost certainly be the multidimensional array youve seen above.
Furthermore, there is a huge amount of possible combinations of datasets. It can be the combination seen above, but it also can be a combination of data from other tables not listed here, and it can be both a bigger or smaller set of tables aggregated into the model and userinput.
Therefore, the process setting the incoming input to the DB must be able to determine dynamically which field of the input must be put into which field of the DB.
I'm doing this for the first time and I don't have a lot of ideas how to do this. The only thing that came to my mind was mirroring the DB column names to the indexes of the input's array and then loop through the model and compare its indexes to the index of the currently selected element of the input. If they match, the value from the respective field of the input will be set to the respective field of the DB.
I am aware that in order for this to work, each column of the tables affected by this process MUST have a unique name across the DB. This is doable though.
Still, this is currently the only idea I could come up with.
However, I wanted to ask you two things about this:
1) Are there other, less "hacky" approaches to solve the problem outlined above?
2) Can someone give me a custom function/a set of custom functions capable of iterating over two arrays, of which at least one will be multidimensional, while comparing their indexes, then setting the value from Array A to Array B when the indexes match?
Below I have a little codeexample, creating two arrays which reproduce the described situation, with which you can fiddle around:
First, the inputside:
$inputArray = array(
"id" => 1,
"internal_key" => "TESTKEY_1",
"CPU" => "intelTest1",
"GPU" => "nvidiaTest1",
"Soundcard" => "AsusTest1"
"MAC" => "macTest1",
"IP" => "ipTest1",
"VLAN" => "vlanTest1"
);
Then, the DB-side:
$modelArray = array(
"id" => 1,
"internal_key" => "TESTKEY_2",
"extensiontable_itc" => array (
"CPU" => "intelTest1",
"GPU" => "nvidiaTest2",
"Soundcard" => "AsusTest1"
),
"extensiontable_sysops" => array (
"MAC" => "macTest2",
"IP" => "ipTest1",
"VLAN" => "vlanTest1"
)
);
I have two, big, 2 dimensional arrays (pulled from some xml data) one (A list) is ~1000 items containing 5 fields the other (B list) is dinamically between 10.000-12.000 items containing 5 fields.
My idea was to compare EACH id key of list A against EACH id key of list B and on "true" compose a new array of combined fields, or just fields from array A if no match.
I used nested foreach loops and ended up with millions of iterations taking long time to process. needless to say...not a solution.
The form of this two structures and my needed result reminded me straight away of a sql join.
The questions are:
1.) Should i try sql or nested foreach might not be the best php way?
2.) Will a relational query be much faster than the iterations?
EDIT:
I pull data only periodically from an xml file (in a separate process) which contains 10+ fields for each node. Than i store the 5 fields i need in a CSV file to later compare with table A that i pull out from a mysql database. basically much like catalog update of attributes with fresh feed.
I'm affraid the original idea of storing into CSV was an error and i should just save the feed updates into a database too.
EDIT 2
The array list B look like this
Array
(
[0] => Array
(
[code] => HTS541010A9E680
[name] => HDD Mobile HGST Travelstar 5K100 (2.5", 1TB, 8MB, SATA III-600)
[price] => 385.21
[avail] => 0
[retail] => asbis
)
...
...
while the A list is similar in all but the 'code' field which is the only one useful for comparison
Array
(
[0] => Array
(
[code] => ASD-HTS541010A
[name] => HDD Mobile HGST Travelstar 5K100 (2.5", 1TB, 8MB, SATA III-600)
[price] => 385.21
[avail] => 0
[retail] => asbis
)
As you can see each feed will have universal code BUT some different random data as prefix or suffix so in each loop i have to do a couple of operations on the string to stripos or compare it to feeds id for a match or close match.
Pseudo code:
$mylist = loadfromDB();
$whslist = loadfromCSV();
foreach ($mylist as $myl) {
foreach ($whslist as $whl){
if ((stripos(code_a,code_b) OR (code_b,code_a) !== false)){
...
}
elseif (stripos(substr(strstr(code_a,'-'),1),code_b) !== false) {
...
}
elseif (stripos( substr(code_a,0,-5);) == !false ){
...
}
}
}
Using SQL will be faster because most SQL engines are optimized for joins, and your method is a brute-force method. However, inserting all that data to MySQL tables is quite a heavy task, so it's still not the best solution.
I suggest you do the join in PHP - but use a smarter algorithm. Start by sorting the two arrays by the field you want to match. Iterate both sorted arrays together - use two iterators(or pointers or indices or whatever) - lets say a iterates over A and b over B. On each iteration of the loop, compare the comparison field of the elements pointed by the a and b. If a's is smaller - advance a. If b's is smaller - advance b. If a's is equal to b's - you have a match, which you should store in a new list, and then advance both a and b(assuming the relation is one-to-one - if it's one-to-many you only advance the many iterator, and if it's many-to-many you need a bit more complex solution).
problem
I have two data tables SEQUENCES and ORGANISMS whose many-to-many-relationship is mappend in the table SOURCES. There is also a 1-m relationshipt between SOURCES and ENTRIES. I will append a detailed structure.
What i want to achieve, is the display of all sequences with all associated organisms and entries, where a condition within the sequences table is met. I have some ideas on how to achieve this, but i need the solution with the best performance, as each of these contains 50k+ entries.
idea one
Select all organisms that belong to the same sequence as a concatenated string in sql, and split it in PHP. I have no idea though, how to do the concatenation in SQL.
idea two
select same sequences with different organisms as distinct records, order by organism, and join them later in php. though this somehow feels just wrong.
idea three
use views. ANY idea on this one appreciated
structure
SEQUENCES
SEQUENCE_ID
DESCRIPTION
ORGANISMS
ORGANISM_ID
NAME
SOURCES
SOURCE_ID
SEQUENCE_ID FK to SEQUENCES.SEQUENCE_ID
ORGANISM_ID FK to ORGANISMS.ORGANISM_ID
ENTRIES
SOURCE_ID FK to SOURCES.SOURCE_ID
ENTRY_VALUE
desired outcome
array(
array(
"SEQUENCE_ID" => 4,
"DESCRIPTION" => "Some sequence",
"SOURCES" => array(
array(
"ORGANISM_ID" => 562,
"ORGANISM_NAME" => "Escherichia coli",
"ENTRIES" => array(
"some entry",
"some other entry"
),
array(
"ORGANISM_ID" => 402764,
"ORGANISM_NAME" => "Aranicola sp. EP18",
"ENTRIES" => array()
)
)
),
array(
"SEQUENCE_ID" => 5,
.....
)
)
PHP5 and FIREBIRD2.5.1
You can't fetch a nested array like that directly from a flat table structure. But if I get you right, what you want to do is not that hard to achieve.
I don't understand why you would concatenate things and then split them again, that's hard to maintain and probably slow.
I see two approaches here:
Fetch everything at once as flat table using JOIN and loop through it in PHP. This approach creates a lot of duplication but it's fast because you can fetch all data in one query and then process it with PHP.
Fetch every entity separately, loop and fetch the next hierarchy level as you go. This approach will be slower. It takes complexity away from the SQL query and doesn't fetch redunant data. It also gives you more freedom as to how you loop through your data and what you do with it.
Alternatively you might want to actually store hierarchical data in a no-sql way, where you could already store the array structure you mentioned.
I come from python background and the python datatype which is similar (a dictionary) is an unordered set of key value pairs.
I am wondering if PHP associative arrays are unordered? They appear to be ordered.
$test = array(
'test' => 'test',
'bar' => 'bar',
);
var_dump($test);
var_dump(array_slice($test, 0, 1));
Test always comes before bar and I can slice this array as you see. So is this always guaranteed to be ordered across php versions? Is the order just the order that I have declared the array with? So something is internally pointing 'test' to place [0] in the array? I have read http://php.net/manual/en/language.types.array.php but it doesn't shed too much light on this issue. I appreciate your responses. Ty
PHP associative arrays (as well as numeric arrays) are ordered, and PHP supplies various functions to deal with the array key ordering like ksort(), uksort(), and krsort()
Further, PHP allows you to declare arrays with numeric keys out of order:
$a = array(3 => 'three', 1 => 'one', 2 => 'two');
print_r($a);
Array
(
[3] => three
[1] => one
[2] => two
)
// Sort into numeric order
ksort($a);
print_r($a);
Array
(
[1] => one
[2] => two
[3] => three
)
From the documentation:
An array in PHP is actually an ordered map. A map is a type that associates values to keys. This type is optimized for several different uses; it can be treated as an array, list (vector), hash table (an implementation of a map), dictionary, collection, stack, queue, and probably more. As array values can be other arrays, trees and multidimensional arrays are also possible.
The documentation states:
An array in PHP is actually an ordered map.
So yes, they are always ordered. Arrays are implemented as a hash table.
From the php manual:
Arrays are ordered. The order can be changed using various sorting functions. See the array functions section for more information.
I have relied on the fact that they are ordered and it has worked consistently in every project I've had.
The array is ordered but that does not mean the keys are sorted, it means that they are in a given order. Where the precise order is not specified, but it appears to be the order in which you introduced the key-value pairs in it.
To understand it, think what would it mean to not be ordered?
Well think to a relation in a relational database.
A relation is not intrinsically ordered: when you access it with a query the database, unless you provide an order clause, can return the same data in any order.
Even if the data was not modified the same data can be returned in different order.
what is the best way to get parent array key with multidimensional arrays?
for example I have this array:
array(
[0] => array(0=> sample, 1=>picture, 2=>frame, 3=>google)
[1] => array(0=> iphone, 1=>orange, 2=>love, 3=>msn)
[2] => array(0=> joe, 1=>geee, 2=>panda, 3=>yahoo)
)
now I need to search for example google and get the parent array key..
which it should be 0...any ideas? I used for loop for this but I think it will be slow if I have arrays with 700000 rows..
If you have an array with 700,000 rows you are almost certainly doing something wrong... I would first recomend thinking about utilizing a different data store: flat file or some type of DB.
foreach($array as $key => $value) {
if(in_array('google', $value)) return $key
}
Arrays with 700,000 rows? How many arrays? 9/10 times problem is that you've got your data set up wrongly.
I'm going to go ahead and assume you're doing a search of some sort. As you can't index an array (in the search meaning of index) then you're probably best putting the data into a database and making the most of column indexing to search fast.
Depending on context, you may alternatively want to think about storing your data in files, one per array, and using file searches to find which file contains your value.