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));
Related
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'];
}
I have the array with values:
$array1 = array('Boss', 'Lentin', 'Endless');
print_r ($array);
The result will be:
Array ( [0] => Boss [1] => Lentin [2] => Endless
It's ok.
But, if I add two elements to this array with a keys, the "Boss" element will be lost.
$array2 = array("1"=>'Doctor','Boss', 2=>'Lynx', 'Lentin', 'Endless');
print_r ($array2);
The result will be:
Array ( [1] => Doctor [2] => Lynx [3] => Lentin [4] => Endless )
//Where is "BOSS"???
Why?
When php create the array, set Doctor in index 1 and Boss in index 2, but 2=>'Lynx' cause php overwrite index 2 and set Lynx in it.
You can set it after setted index or use index for it. For example like
$array2 = array("1"=>'Doctor', 2=>'Lynx', 'Boss', 'Lentin', 'Endless');
// or
$array2 = array("1"=>'Doctor', 2=>'Boss', 3=>'Lynx', 'Lentin', 'Endless');
When $array is being created, 'Boss' will first be stored in index 2 (Array([2] =>'Boss') which is later overwritten by 'Lynx'
Your issue is index keys
$array2 = array("1"=>'Doctor','Boss', 2=>'Lynx', 'Lentin', 'Endless');
print_r ($array2);
This is because, on index 1 it is already doctor, boss will be second, which will be replaced by Lynx which have same index of 2 where boss will be replaced.
I hope I am clear.
This is expected behaviour from php (see http://php.net/manual/en/language.types.array.php#example-57). In case you need all the values in the array and don't need to work with keys, I recommend to use array_push($array $value). Otherwise you should add all the values with their keys and remember that for PHP 1 and "1" and true are the same values so they will overwrite each other.
array() is a construct with dynamic arguments representing literal arrays. The assignment of the given values to the array structure is done sequentially i.e. one by one from left to right. In your example:
Doctor is assigned to index 1.
Boss is assigned to index 2.
Lynx overwrites index 2.
Lentin and Endless are assigned to index 3 and 4 respectively.
hey #Weltkind first of all i suggest you to read
"http://php.net/manual/en/language.types.array.php",
now come to your answer In php the array key can be string or integer and if you do not mention the key then
default integer is set and the value of next array key is depending on the previous array integer key means
next array key = previous integer key + 1;
In PHP array the same key value will override by the same key
Now lets understand with your array2:
<?php
$array2 = array("1"=>'Doctor','Boss', 2=>'Lynx', 'Lentin', 'Endless');
1) as you started your array with key "1" so the
so for 1st key value is [1] => 'Doctor'
current array like: array([1] => 'Doctor')
now next key = previous integer key(that is 1) + 1 = 2;
2) for 2nd key value is [2] => 'BOSS'
current array like: array([1] => 'Doctor', [2] => 'BOSS')
3) next key = previous integer key(that is 2) + 1 = 3 it will carry
to next key but as next key is [2] => 'Lynx' as you mentioned so at
key [2] the value will be override by value 'BOSS' to 'Lynx'; current
array like : array([1] => 'Doctor', [2] => 'Lynx')
Now the next key we have is [3]
4) for next value the key is [3] => 'Lentin'
current array like : array([1] => 'Doctor', [2] => 'Lynx', [3] =>
'Lentin');
now next key = previous integer key(that is 3) + 1 = 4;
5) for next value the key is [4] => 'Endless'
current array like : array([1] => 'Doctor', [2] => 'Lynx', [3] =>
'Lentin', [4] => 'Endless');
and that is why the final array is like below :
array(
[1] => 'Doctor',
[2] => 'Lynx',
[3] => 'Lentin',
[4] => 'Endless'
);
Ok so im trying to grab a single part of an array, the array is the return for some stats there can be up to 8 players in the server, the data i get is like this
Array (
[0] => 1
[1] => Player1
[2] =>
[3] => 1
[4] => 0
[5] => 0
[6] => 0
[7] => 0
[8] => 1
[9] => Player2
[10] =>
[11] => 1
[12] => 0
[13] => 0
[14] => 0
[15] => 0
)
so that is the return for 2 players, as i said it can be up to 8, anyway i am trying to just grab the player names and im not sure how to go about it ( Player1 , Player2 ) is the only data i need, any help is appreciated, it always returns 8 pieces of data per player never more never less if that makes it easier
(sorry for bad english)
If you have control over the return type, I would restructure the array being returned either into an Object or an array of arrays where each sub array contains all of the information for one player.
I you don't have control over the return type and the Player's name is always in the second position within the return array you can use a while loop to iterate over the array. Use a counter starting at 1 and then increment the counter by 8 each time through the loop. For example:
$i= 1;
while ($i < count($return_var)) {
$name = $return_var[$i];
// do something w/ name
$i += 8;
}
You want to get all items that are not '' (assuming empty string), 0 or 1 (assuming integers here):
$playerNames = array_diff($array, array('', 0, 1));
If you more specifically know what the format of the array actually is, you can also create some little "parser":
$playerSize = 8;
$playerFields = array('_1', 'name', '_3', '_4', '_5', '_6', '_7', '_8');
$players = array_chunk($array, $playerSize);
foreach($players as &$player)
{
$player = (object) array_combine($playerFields, $player);
}
unset($player);
This does parse $array into another array $players that contains one object per each player. Each object has the name property now:
printf("%d Player(s):\n", count($players));
foreach($players as $i => $player)
{
printf("#%d: %s\n", $player->name);
}
if the array you pasted is called $array and the values of the places without players are always numeric (like your example), this code will work:
$players = array();
foreach($array as $player){
if(!empty($player) && !is_numeric($player){
$players[]=$player;
}
}
var_dump($players);
I have two PHP arrays. One contains a group name and another contains a pay wage value.
$group_wages_array = Array ( [0] => 1 [1] => 4 [2] => 1 [3] => 3 );
This means there are four employees on the schedule. Two are assigned to group 1, another to group 4 and the last to group 3.
The second array is as follows:
$tot_wages_array = Array ( [0] => 500 [1] => 44 [2] => 80 [3] => 11.25 );
This is a sample array of each employee's wage. Both arrays are constructed in order as values are added in a mysql while loop as it pulls the info from the database.
Later on down the line, I combine the two arrays to get one array where the key is the group number and the value is the total wages for that group:
$combined_group_wages = array_combine($group_wages_array, $tot_wages_array);
This works like a charm EXCEPT for when more than one employee is assigned to the same group. These arrays are built in a mysql while loop as it loops through each employee's info:
array_push($tot_wages_array, $totemp_wages_sch); // Add their wage to the array
array_push($group_wages_array, $emp_data['group_id']); // Add their group to the array
Instead of just pushing the data to the array, I need to do this... I know the english but I don't know how to code it:
If $emp_data['group_id'] exists as value in $group_wages_array, add nothing to this array but get the key. Add $totemp_wages_sch to $tot_wages_array where key = group_wages_array key
I know it sounds more like an SQL query but I have to keep the keys and values in order so that they can be combined later in the page. If I can get this to work right, The arrays shown in the example would be:
$group_wages_array = Array ( [0] => 1 [1] => 4 [2] => 3 );
$tot_wages_array = Array ( [0] => 580 [1] => 44 [2] => 11.25 );
$combined_group_wages = array_combine($group_wages_array, $tot_wages_array);
$combined_group_wages = Array ( [1] => 580 [4] => 44 [3] => 11.25 );
...I've got to make this work using PHP. Any ideas?
I came up with a solution based on a combination of two of the answers submitted below. Here it is if it can help someone:
if(in_array($emp_data['group_id'], $group_wages_array)){
$key = key($group_wages_array);
$tot_wages_array[$key] += $totemp_wages_sch;
} else {
array_push($group_wages_array, $emp_data['group_id']);
array_push($tot_wages_array, $totemp_wages_sch);
}
This should do it:
$group_wages_array = array(1, 4, 1, 3);
$tot_wages_array = array(500, 44, 80, 11.25);
$combined_group_wages = array();
for ($i=0; $i<count($group_wages_array); $i++) {
$group = $group_wages_array[$i];
if (array_key_exists($group_wages_array[$group], $combined_group_wages)) {
$combined_group_wages[$group] += $tot_wages_array[$i];
} else {
$combined_group_wages[$group] = $tot_wages_array[$i];
}
}
print_r($combined_group_wages);
Yields:
Array
(
[1] => 580
[4] => 44
[3] => 11.25
)
But I recommend that you just switch to using objects to better represent your data.
If I could see the entirety of the code that would help a lot, but here's your English converted to php. Show me more code and I can perfect it, until then try this ->
if(in_array($emp_data['group_id'], $group_wages_array)){
$key = key($group_wages_array);
$tot_wages_array[$key] = $totemp_wages_sch;
} else {
array_push($group_wages_array, $emp_data['group_id']);
}
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.