PHP Array length - php

So this may be a bit long winded to explain, but I'll try to make it concise.
I have a db query that pulls in 3 different Tag IDs, 2 of them are associated to 4 Hub IDs, while 1 is associated with only 3.
I return all tags, and sort the results by ID (so all 4 results for tag 1 are grouped, all 4 of 2, and all 3 of 3) Like so:
Array
(
[0] => 40BD32751DF1
[1] => 40BD32751DF1
[2] => 40BD32751DF1
[3] => 40BD32751DF1
[4] => 10CEA9FD173A
[5] => 10CEA9FD173A
[6] => 10CEA9FD173A
[7] => 10CEA9FD173A
[8] => 10CEA9FCFE26
[9] => 10CEA9FCFE26
[10] => 10CEA9FCFE26
)
Then I do a while loop and loop it for each Tag ID (3x). Inside that, I use array_keys on an array_column search to find the array indexes of each Tag ID, count how many results I have (4, 4, 3) I then take that row's data using the array key, and loop number to push that row of data into an array for later sorting:
while($currentTag = pg_fetch_assoc($tagList)) {
$tkeys = array_keys(array_column($tagDataArray, 'devmac'), $currentTag['devmac']);
$tempArray = array();
for($k=0; $k < count($tkeys); $k++){
array_push($tempArray, $tagDataArray[$tkeys[$k]]);
}
//Then I sort that temporary array so one of the values in the row is the highest:
foreach($tempArray as $sigkey => $sigrow) {
$sigsort[$sigkey] = $sigrow['devrssi'];
}
array_multisort($sigsort, SORT_DESC, $tempArray);
updateArticles($tempArray[0]);
}
Now the problem comes from that temporary array. I have 4 results for the first ID, 4 for the second, then 3 for the third, yet for the third ID, somehow I still get 4 items in the array even though I reinitialize it with each while loop pass (each ID). The fourth result from the second ID, ends up as the fourth result for the third ID.
How is this possible? I've been trying to figure this out for hours and I'm not making any headway. The $tkeys gives me 3 on the third ID, so the for loop runs 3 times, everything makes sense, till the array push where something just decides to stick around. I've even added a print_r to the tempArray and before it runs the third time, it's empty! I dont get where it keeps creeping back in.
Thanks.

Make sure that when you process data in subsequent loops, you remove all previous data...
$sigsort= [];
foreach($tempArray as $sigkey => $sigrow) {
$sigsort[$sigkey] = $sigrow['devrssi'];
}

Related

Php, problem with increasing key value by 1

I have spent now 2 days figuring out this problem. I'm trying to create voting script which reads .txt file and modifies values inside it. I have problem with foreach part where I try to add +1 in votes of person. 1-5 is id of person, number after | is amount of votes. First output is:
Array
(
[0] => 1|2
[1] => 2|6
[2] => 3|8
[3] => 4|3
[4] => 5|10
and I want it to add just +1 in last number. But if I try to use increment, I get error: "PHP Fatal error: Cannot increment/decrement overloaded objects nor string offsets in..."
foreach ($file_contents as &$id) {
if ($id == 2) {
$id[2]++;
}
}
print_r($file_contents);
I'm still learning PHP and this is weird to me, because just giving "$id[2] = 8" actually modifies that value. Why ++ can't be used? What's way around this?
Array
(
[0] => 1|2
[1] => 2|8
[2] => 3|8
[3] => 4|3
[4] => 5|10
)
Use json instead. It will make your life much easier.
Json is a text string that can be decode in to an array.
Either a indexed array or an associative array. Associative is preferred in this case in my opinion.
$votes = ["1" => 2, "2" => 6, "3" => 8, "4" => 3, "5" => 10];
// Above is an associative array with the same data as your example.
// The key is the id and the value is the votes.
// To read it from the file use:
// $votes = json_decode(file_get_contents("file.txt"));
$inputVote = 2; // someone voted on person 2.
if(!isset($votes[$inputVote])) $votes[$inputVote] = 0; // if someone voted on a person not already in the array, add the person to the array.
$votes[$inputVote]++; // increments the votes on person 2.
file_put_contents("file.txt", json_encode($votes));

PHP Array of arrays made unique

I have an array of arrays as following:
$a = array(
1 => array("sport", "geo"),
2 => array("sport", "geo", "history"),
3 => array("geo", "history"),
4 => array("golf", "sport"),
...
);
From that I need to get keys, in such a way so that values are unique.
So from that I would need to get something like:
$b = array( 1, 3, 4 );
$a[2] would be cut out, since it has the same values as $a[1], but since $a[2] is not there, $a[3] is fine.
If some values get completely cut out, that's fine. I will have 30+ keys, from which I need to get 10, which have unique values.
Key is a question ID, and values are tags.
I want to get 10 questions, which are different from each other (so that I don't get 10 questions about Sport).
I tried array_unique(), but that just returns this:
Array (
[1] => Array (
[0] => sport
[1] => geo
)
)
which doesn't seem to help much.
Can you guys point me towards something that could help me?
I guess I could try to list all possible categories, make that array unique, sort it by random. I would need to preserve Keys, but Keys are unique...
you can use array_diff() to detect unique tags
Returns an array containing all the entries from array1 that are not present in any of the other arrays.
Then use array_merge() to store unique value to our $tags variable
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.
<?php
$a = array(
1 => array("sport", "geo"),
2 => array("sport", "geo", "history"),
3 => array("geo", "history"),
4 => array("golf", "sport")
);
$tags = [];
foreach($a as $tag){
$tags = array_merge($tags, array_diff( $tag, $tags));
}
print_r($tags);
Output :
Array
(
[0] => sport
[1] => geo
[2] => history
[3] => golf
)
Just iterate through the initial array of questions, every time save the value (array of tags) to another temporary array with checking if actual tags already exists in temporary array - if not add the question to temporary array, if exists go next. Do it until you have 10 questions in your temporary array, if you finish the question array without already having 10 questions - repeat the iteration but this time add other questions even if the tags are repeating - until you have 10.

2 or more arrays from a list

I am quite not able to get the logic for my requirement.
Lets consider I have an array
Array
(
[0] => 1
[1] => 1
[2] => 2
[3] => 1
[4] => 3
[5] => 3
)
I would like to split the below array on the basis if the array element matches its previous element.
i.e in the above example value at [1] matches the value at [0]. Hence put it into the same array as [0]. Now check if the value at [2] matches the value at [1] if it matches put it into the same array, if not put it into a different array. The process continues.
Below is an example of the desired outpout.
Array
(
[0] => 1
[1] => 1
)
Array
(
[0] => 2
)
Array
(
[0] => 1
)
Array
(
[0] => 3
[1] => 3
)
Thanks for your help in advance.
Justin
you can obtain that result in a loop checking on previous element. the output can be an array of arrays! (or anything you would prefer.. do your thing here)
$array1 = array(1, 1, 2, 1, 3, 3);
$output_array=array();
$previous_value="";
$output_array_index=0;
foreach ($array1 as $value) {
if($value != $previous_value){
$output_array_index+=1;
}
$output_array[$output_array_index][]=$value;
$previous_value=$value;
}
print_r($output_array);
so, let me know if you need more pointers! array logic is fun, and php will let you do alot, out of the box. though this specific need is not covered, have a look when you have a minute # the manual, it'll save you time in the future, guarantee http://php.net/manual/en/ref.array.php
This question is a bit confusing but doesn't sound too difficult to implement if I'm understanding it correctly. All you need to do is have a temporary array (or array list) that checks user input. If that user input happens to be the same as the previous input (you can keep a counter variable and check to see if ArrayList.get(counter) == ArrayList.get(counter-1)). Keep adding things to this temporary arrayList and once you have a number that is different, just iterate through the arraylist and add it to a new array.
Another question you have to consider is how you are going to store all these arrays. For that you may want to create an ArrayList containing Arrays. That way after you find user input that is different from the previous input you can just use the toArray method provided with the ArrayList class and add it to the ArrayList containing all of your separate Arrays!
Hope this helps!

Pseudo code for retrieving MySQL data with PHP associative arrays

I have two MySQL tables, products and prodGroups. I need to retrieve the following data in this format of an associative array:
Array ( [0] => Product Group 1 => Item 1
=> Item 2
=> Item 3
[1] => Product Group 2 => Item 4
=> Item 5
=> Item 6
[2] => Product Group 3 => Item 7
=> Item 8
=> Item 9 )
The above was freely written so obviously that's not correct format of print_r for an assoc array, but hopefully you get the idea.
I'm having trouble comprehending to retrieve Items from a MySQL table where their prodGroup value matches the name of Product Group 1/2/3. I want the items belonging to a particular product group to be apart of its rightful parent array.
I'm not the best at explaining, hope what I've written is enough to point my question across. However, in summary if you're still lost, I need Item 1&2&3 to be apart of Product Group 1 in the array.
Pseudo code would be great, I have a feeling a while and foreach loop is required, I'm just totally lost for its structure.
You can solve this in one of two ways:
1) With nested queries. For small amounts of data, why not:
while($row = getNextProductGroup())
$row->items = getItemsForGroup($row->ProductGroupId);
2) If you have lots of data this will be costly in performance, so you'll need a smarter way. Just join them together and pick it apart in PHP:
$productGroups = [];
while($row = getNextProductGroupAndItem()) {
if(!isset($productGroups[$row->ProductGroupId])) {
$row->items = [];
$productGroups[$row->ProductGroupId] = $row;
}
$productGroups[$row->ProductGroupId]->items[] = $row;
}

manipulate multiarrays

I am pulling some data from a mysql table via the following:
$result = mysql_query("SELECT characters_ID, name, borndate, deathdate, marrieddate, ispregnant FROM characters WHERE isfemale='1'",$db);
$femaledata = array();
while ($row_user = mysql_fetch_assoc($result))
$femaledata[] = $row_user;
This gives me an array that looks like this:
Array (
[0] => Array ( [characters_ID] => 2 [name] => Helene [borndate] => 35 [deathdate] => 431 [marrieddate] => 157 [ispregnant] => 0 )
[1] => Array ( [characters_ID] => 4 [name] => Isabelle [borndate] => 161 [deathdate] => [marrieddate] => 303 [ispregnant] => 1 )
[2] => Array ( [characters_ID] => 7 [name] => Helene [borndate] => 326 [deathdate] => [marrieddate] => [ispregnant] => 0 )
[3] => Array ( [characters_ID] => 72 [name] => Faylinn [borndate] => 335 [deathdate] => [marrieddate] => [ispregnant] => 0 )
[4] => Array ( [characters_ID] => 74 [name] => Relina [borndate] => 349 [deathdate] => [marrieddate] => [ispregnant] => 0 )
)
Now I need to remove any characters who have a value for deathdate or ispregnant, and then I need to run some code on the others. For instance I need to grab the borndate value, compare it to the current date to find age, and based partly on age, I need to run code for each to determine if the character has become pregnant on the turn.
Apologies that this seems like a long-reaching question. Multidimensional arrays still seem to confound me.
Edit: (question needs to be more clear)
Can you please suggest the best way that I would either explode or break up the array, and then do conditional modification to the data, or instead how I could remove unneeded data and then do conditional modification to the data.
My ultimate output here would be taking suitable female characters (not dead or pregnant already), and based on their age, giving them a chance at becoming pregnant. If true, I'd throw some code back at the SQL database to update that character.
Thanks!
All the things you need could probably get done with SQL :
Now I need to remove any characters who have a value for deathdate or
ispregnant
Simply add some argument to your WHERE condition :
isPregnant IS NULL AND deathdate IS NULL
For instance I need to grab the borndate value, compare it to the
current date to find age
Depending of your field format the maths could be done in SQL , have look to the DATE function of mysql
Don't underestimate the power of your sql server , 99% of the time it is probably faster than php to work on data set.
Instead if immediately removing some rows from your array, try limiting the data you recieve through SQL.
You can loop through your array like this:
foreach($femaledata as $female)
{
echo $female['name'];
}
do you mean something like this?
$femaledata = array();
while ($row_user = mysql_fetch_assoc($result)) {
$ok = false;
// do you validation for every user
if($ok) array_push($femaledata,$row_user);
}
TJHeuvel gave you the right answer, and you should accept that answer. However, to inform: multidimensional arrays need not confound. Let me see if I can explain.
In PHP, you can put any object at all into an array, including other arrays. So, let's say you have an array that contains other arrays. When you iterate over that array using a looping construct (usually a foreach loop), each iteration of the loop will give you another array; if you want to access the elements of this sub-array, just loop over it. This is called a nested loop. Example:
$r = array(
array(1,2,3),
array(4,5,6),
array(7,8,9)
);
foreach ($r as $cur) {
foreach ($cur as $num) {
echo $num;
}
}
In each iteration of the outer loop, $cur contains an array; the inner loop iterates over contents of this array. This technique allows you to process arrays of any dimension.
However, in your specific case, you don't need to use an inner loop to iterate over your subarrays. You only need to access certain elements of your subarrays by their keys, rather that processing all of them in turn. So, a simple foreach loop will do.

Categories