Sort and associaative array by specific value - php

If this has been answered before I apologize (I haven't seen to found it). I have a game pool website that wishes to sort by points (pts). In the below example I want 'Team B' to be first as their points are higher then Team A's at 22 compared to 12. While the solution on this page (How to sort an array of associative arrays by value of a given key in PHP?) seemed to be very similar to what I was looking for I wasn't able to get it to work.
Array
(
[0] => Team Object
(
[id] => 5
[name] => Team A
[games_played] => 13
[wins] => 6
[losses] => 7
[ot_losses] => 0
[pts] => 12
[goals_for] => 7.5
[goals_against] => 22
[streak] => 6-7
)
[1] => Team Object
(
[id] => 2
[name] => Team B
[games_played] => 13
[wins] => 11
[losses] => 2
[ot_losses] => 0
[pts] => 22
[goals_for] => 51
[goals_against] => 19
[streak] => 11-2
)
I suspect I'm on the right path with the following but missing something...
$new_array = array();
foreach ($array_objects as $key => $row)
{
$new_array[$key] = $row['pts'];
}
array_multisort($price, SORT_DESC, $array_objects);

Related

How can I loop my array to total the score percentage based on his correct answer?

I have this response
[0] => Array (
[name] => Test
[question_id] => 4
[question_choice_id] => 14
[choice_level] => 0
)
[1] => Array (
[name] => Test
[question_id] => 5
[question_choice_id] => 19
[choice_level] => 0
)
[2] => Array (
[name] => Test
[question_id] => 6
[question_choice_id] => 24
[choice_level] => 0
)
[3] => Array (
[name] => Test
[question_id] => 7
[question_choice_id] => 26
[choice_level] => 0
)
[4] => Array (
[name] => Test
[question_id] => 8
[question_choice_id] => 29
[choice_level] => 1
)
[5] => Array (
[name] => Test
[question_id] => 9
[question_choice_id] => 36
[choice_level] => 0
)
[6] => Array (
[name] => Test
[question_id] => 1
[question_choice_id] => 2
[choice_level] => 0
)
[7] => Array (
[name] => Test
[question_id] => 2
[question_choice_id] => 7
[choice_level] => 0
)
[8] => Array (
[name] => Test
[question_id] => 3
[question_choice_id] => 9
[choice_level] => 0
)
I want to get the percentage of the user with the formula of
Score = the_right_answer / total_count_array * 100
The correct answer has a value of 1 in the choice_level columns
so for my example is, the formula should be
Score = 1/ 9 * 100
How can I get the total from this array?
Once I get the answer I just like to return them to my view.
public function progress(){
$category_id = Session::get('category_id');
$user_set_id = Session::get('user_set_id');
$score = Answer::get_user_score($user_set_id,$category_id);
return view('pages.user.user_progress', [
'name' => '',
'score' => '',
]);
}
Can anyone help me on how to do this properly? any help would be really appreciated.
Based on Score = total count_of_array / the_right_answer * 100:
for total count_of_array could be calculated easily using count($answes)
for calculating the_right_answer, you can use array_map() or manual loop:
$total = count($answers);
$correct = 0;
foreach($answers as $answer){
if($answer['choice_level'] == '1'){
$correct++;
}
}
the snippet above will give you $correct as total correct answer
Now that you have the needed data, you can then do the calculation yourself. However, I would remind you that when the user doesn't have any correct answer, you will face a Division by zero warning. Keep that in mind😉
Since apparently choice_level can only take the values 0 or 1 you can use array_sum to get the number of correct answers. You will need to reduce the response array to just that field first, you can achive that with array_column. So all together:
$score = array_sum(array_column($answers, 'choice_level')) / count($answers) * 100;
for each($arrayname['score'] as $item){
}

php combine two array's subarrays where value of certain key is equal

Hello & thanks for your interest
I do have two arrays:
[A] -from the mysql query of one database on server1- the
$postings_array - a SELECT of all postings of a discussion-thread
(based on the thread's id)
[B] -from the mysql query of an other database on server2 - the
$usersdata_array - a SELECT of all postings of a discussion-thread
(based on the thread's id)
This means:
in [A] there are many postings-sub-arrays and in [B] one or more
userdata-sub-arrays.
both arrays always do include a key named usrsID in each of their
subarrays.
I need to extend the Sub-Arrays in $postings_array [A]
by merging them
with the Sub-Arrays of the $usersdata_array [B]
based on WHERE the VALUE of the usrsID KEY in the sub-array[A] is EQUAL to the usrsID KEY in the sub-array[B].
EXAMPLE:
Array [A]:
(
[0] => Array
(
[ID] => 5
[usrsID] => 3
[tid] => 19
[txtid] => 22
)
[1] => Array
(
[ID] => 6
[usrsID] => 1
[tid] => 19
[txtid] => 23
)
[2] => Array
(
[ID] => 7
[usrsID] => 2
[tid] => 19
[txtid] => 24
)
[3] => Array
(
[ID] => 8
[usrsID] => 1
[tid] => 19
[txtid] => 25
)
)
--
Array [B]:
(
[0] => Array
(
[id] => 1
[usrsID] => 1
[avatarID] => 1
)
[1] => Array
(
[id] => 2
[usrsID] => 2
[avatarID] => 3
)
[2] => Array
(
[id] => 3
[usrsID] => 3
[avatarID] => 22
)
)
needed result (the by [B] extended [A] for the example above):
Array [A_extended]:
(
[0] => Array
(
[ID] => 5
[usrsID] => 3
[tid] => 19
[txtid] => 22
[id] => 3
[avatarID] => 22
)
[1] => Array
(
[ID] => 6
[usrsID] => 1
[tid] => 19
[txtid] => 23
[id] => 1
[avatarID] => 1
)
[2] => Array
(
[ID] => 7
[usrsID] => 2
[tid] => 19
[txtid] => 24
[id] => 2
[avatarID] => 3
)
[3] => Array
(
[ID] => 8
[usrsID] => 1
[tid] => 19
[txtid] => 25
[id] => 1
[avatarID] => 1
)
)
... I think, it's a common problem so there should be a best-practice around (may be in one inbuild php function or a combination of two or three of them) - and I do not have to reinvent the wheel.
At least, I hope so...
else, my approach would be
check the amounts of iterations (= the subarrays found in the $usersdata_array [B] )
iterate over the outerHaystack and trigger a function when $needle was found in innerHaystack
perform merge via checkSubArrayfunc
Approach,
with hayStackArray = complete [A]Array;
needle = $usrsID value of [B] Sub-Array:
function checkSubArrayfunc($hayStackSubArray, $needle, $toMergeSubArray) {
if (in_array(array('$hayStackSubArray'), $needle)) {
array_merge_recursive($hayStackSubArray, $toMergeSubArray);
}
}
Try this:
foreach($arr_b as $b_item) {
foreach($arr_a as $key => &$a_item) {
if ($b_item['usrsID'] == $a_item['usrsID']) {
$a_item['id'] = $b_item['usrsID'];
$a_item['avatarID'] = $b_item['avatarID'];
}
}
}
Your output of $_arr_a will be:
Array
(
[0] => Array
(
[ID] => 5
[usrsID] => 3
[tid] => 19
[txtid] => 22
[id] => 3
[avatarID] => 22
)
[1] => Array
(
[ID] => 6
[usrsID] => 1
[tid] => 19
[txtid] => 23
[id] => 1
[avatarID] => 1
)
[2] => Array
(
[ID] => 7
[usrsID] => 2
[tid] => 19
[txtid] => 24
[id] => 2
[avatarID] => 3
)
[3] => Array
(
[ID] => 8
[usrsID] => 1
[tid] => 19
[txtid] => 25
[id] => 1
[avatarID] => 1
)
)
At first take an empty array for store marged array. then traversed in both array. if the userID are be same in both the array of element then marge these array and push in margeArr.
$margeArr = [];
foreach($Array_A as $a){
foreach($Array_B as $b){
if($a['usrsID'] == $b['usrsID']){
array_push($margeArr,array_merge($a,$b));
}
}
}
print_r($margeArr);
Comment by the questionaire:
It's a great solution - it really meets the requirements described in my question and merges the to be marged Array with the key-value-pairs of the "to be injected"-Array.
But I prefere the bestprogrammersinintheworld's solution, where I can rename the keys "en passant / on-the-fly":
foreach($arr_b as $b_item) {
foreach($arr_a as $key => &$a_item) {
if ($b_item['usrsID'] == $a_item['usrsID']) {
$a_item['myNewKeyName1'] = $b_item['usrsID'];
$a_item['myNewKeyName2'] = $b_item['avatarID'];
}
}
}
print("<pre>".print_r($arr_a,true)."</pre>");
Sorting my advice from best to worst...
Joining this data should be done before PHP is necessary. Depending on the location of the two sources, this may be trivial, but JOINing via SQL is the best, most direct, most professional option. These links may be helpful:
access two different databases on different servers in the same query
Joining Tables from different Database
In lieu of option 1, declare and leverage a lookup array (in PHP) which would have the identifying column as its first level keys. Then you don't need to nest another loop to relate the two data sets.
$lookup = array_column($arrayB, null, 'usrsID');
foreach ($arrayA as $row) {
$result[] = $row + ($lookup[$row['usrsID']] ?? []);
}
The worst option which I do NOT recommend is writing a nested loop with a condition inside of it. All previous answers are doing this -- and slowing down an already inefficient approach, they don't even break inside the condition block.

PHP How To Turn Nested Foreach Into An Array of Arrays (Multidimensional Array)

I'm sorry because I'm probably not going to use the correct vocabulary here, but I'm trying to figure out "how-to" modify the following code so that it creates the array of arrays (Multidimensional Array). This code creates the structure illustrated in the image below, but I want it to create the array of arrays (Multidimensional Array) instead.
Basically, I want the 1001, 1002, 1004, etc... to be the main array. The nested arrays will be the strings that has the #1001, #1002, etc... in them. You'll notice the # in the string corresponds with number in the original array.
$combinedAssignmentData = [];
foreach($assignmentsYES as $key=>$assignedIDs){
$levels = array($assignedIDs);
foreach($levels as $key=>$level){
echo "<strong>$level</strong><br>";
foreach($studentIDsubmissions as $k=>$individualSubmission){
if (strpos($individualSubmission, $level) !== false) {
echo "--$individualSubmission<br>";
}
}
}
}
var_export($assignmentsYES);
array ( 0 => '1001', 1 => '1002', 2 => '1004', 3 => '1005', 4 => '1007', 5 => '1008', 6 => '1009', 7 => '1015', 8 => '1028', 9 => '1029', )
var_export($studentIDsubmissions);
array ( 0 => '346623#guhsd.net|TD-Share Test #1001|NO', 1 => '346623#guhsd.net|TD-Share Test #1001|NO', 2 => '346623#guhsd.net|TD-Share Test #1001|NO', 3 => '346623#guhsd.net|TD-Share Test #1001|NO', 4 => '346623#guhsd.net|TD-No Excuse Reflection #1002|YES', 5 => '346623#guhsd.net|TD-No Excuse Reflection #1002|YES', 6 => '346623#guhsd.net|TD-No Excuse Reflection #1002|YES', 7 => '346623#guhsd.net|TD-About Me #1004|YES', 8 => '346623#guhsd.net|TD-Calendar #1007|YES', 9 => '346623#guhsd.net|TD-Wage Tracker #1008|YES', 10 => '346623#guhsd.net|TD-Stock Portfolio #1009|YES', 11 => '346623#guhsd.net|TD-Collaboration #1005|YES', 12 => '346623#guhsd.net|TD-Stock Portfolio #1009|YES', 13 => '346623#guhsd.net|TD-Collaboration #1005|YES', 14 => '346623#guhsd.net|TD-Dream Vacation Presentation #1015|YES', )
Any help is greatly appreciated!
Todd
Here you go
$assignmentsYES = array ( 0 => '1001', 1 => '1002', 2 => '1004', 3 => '1005', 4 => '1007', 5 => '1008', 6 => '1009', 7 => '1015', 8 => '1028', 9 => '1029', );
$studentIDsubmissions = array ( 0 => '346623#guhsd.net|TD-Share Test #1001|NO', 1 => '346623#guhsd.net|TD-Share Test #1001|NO', 2 => '346623#guhsd.net|TD-Share Test #1001|NO', 3 => '346623#guhsd.net|TD-Share Test #1001|NO', 4 => '346623#guhsd.net|TD-No Excuse Reflection #1002|YES', 5 => '346623#guhsd.net|TD-No Excuse Reflection #1002|YES', 6 => '346623#guhsd.net|TD-No Excuse Reflection #1002|YES', 7 => '346623#guhsd.net|TD-About Me #1004|YES', 8 => '346623#guhsd.net|TD-Calendar #1007|YES', 9 => '346623#guhsd.net|TD-Wage Tracker #1008|YES', 10 => '346623#guhsd.net|TD-Stock Portfolio #1009|YES', 11 => '346623#guhsd.net|TD-Collaboration #1005|YES', 12 => '346623#guhsd.net|TD-Stock Portfolio #1009|YES', 13 => '346623#guhsd.net|TD-Collaboration #1005|YES', 14 => '346623#guhsd.net|TD-Dream Vacation Presentation #1015|YES', );
$combinedAssignmentData = [];
foreach($assignmentsYES as $key=>>$level){
$combinedAssignmentData[$level] =
array_filter(
$studentIDsubmissions,
function($item)use($level){
return strpos($item, '#'.$level) !== false;
}
);
}
print_r($combinedAssignmentData);
Output
Array
(
[1001] => Array
(
[0] => 346623#guhsd.net|TD-Share Test #1001|NO
[1] => 346623#guhsd.net|TD-Share Test #1001|NO
[2] => 346623#guhsd.net|TD-Share Test #1001|NO
[3] => 346623#guhsd.net|TD-Share Test #1001|NO
)
[1002] => Array
(
[4] => 346623#guhsd.net|TD-No Excuse Reflection #1002|YES
[5] => 346623#guhsd.net|TD-No Excuse Reflection #1002|YES
[6] => 346623#guhsd.net|TD-No Excuse Reflection #1002|YES
)
[1004] => Array
(
[7] => 346623#guhsd.net|TD-About Me #1004|YES
)
[1005] => Array
(
[11] => 346623#guhsd.net|TD-Collaboration #1005|YES
[13] => 346623#guhsd.net|TD-Collaboration #1005|YES
)
[1007] => Array
(
[8] => 346623#guhsd.net|TD-Calendar #1007|YES
)
[1008] => Array
(
[9] => 346623#guhsd.net|TD-Wage Tracker #1008|YES
)
[1009] => Array
(
[10] => 346623#guhsd.net|TD-Stock Portfolio #1009|YES
[12] => 346623#guhsd.net|TD-Stock Portfolio #1009|YES
)
[1015] => Array
(
[14] => 346623#guhsd.net|TD-Dream Vacation Presentation #1015|YES
)
[1028] => Array
(
)
[1029] => Array
(
)
)
Sandbox
*PS
I added a # in here strpos($item, '#'.$level), which will improve the accuracy a bit. It would be better to use a regular expression (in the array filter callback)
function($item)use($level){
return preg_match('/#'.$level.'\|/', $item); //match `#{id}|`
}
Consider for example matching 1001 to id 10012 ~ strpos will just match the 1001 part with no regard.
If the oddly numbered keys for the sub array bug you you can wrap the array_filter in array_values(array_filter(....)); to reset them. Array filter retains the keys from the original array. In most cases the keys don't really matter, so I wouldn't worry about it unless you really have to.
Update
After thinking about it and posting this
be better to use a regular expression
Why don't we go with this one:
$assignmentsYES = array ( 0 => '1001', 1 => '1002', 2 => '1004', 3 => '1005', 4 => '1007', 5 => '1008', 6 => '1009', 7 => '1015', 8 => '1028', 9 => '1029', );
$studentIDsubmissions = array ( 0 => '346623#guhsd.net|TD-Share Test #1001|NO', 1 => '346623#guhsd.net|TD-Share Test #1001|NO', 2 => '346623#guhsd.net|TD-Share Test #1001|NO', 3 => '346623#guhsd.net|TD-Share Test #1001|NO', 4 => '346623#guhsd.net|TD-No Excuse Reflection #1002|YES', 5 => '346623#guhsd.net|TD-No Excuse Reflection #1002|YES', 6 => '346623#guhsd.net|TD-No Excuse Reflection #1002|YES', 7 => '346623#guhsd.net|TD-About Me #1004|YES', 8 => '346623#guhsd.net|TD-Calendar #1007|YES', 9 => '346623#guhsd.net|TD-Wage Tracker #1008|YES', 10 => '346623#guhsd.net|TD-Stock Portfolio #1009|YES', 11 => '346623#guhsd.net|TD-Collaboration #1005|YES', 12 => '346623#guhsd.net|TD-Stock Portfolio #1009|YES', 13 => '346623#guhsd.net|TD-Collaboration #1005|YES', 14 => '346623#guhsd.net|TD-Dream Vacation Presentation #1015|YES', );
$combinedAssignmentData = [];
foreach($assignmentsYES as $key=>$level){
$combinedAssignmentData[$level] = preg_grep('/#'.$level.'\|/', $studentIDsubmissions);
}
print_r($combinedAssignmentData);
Using Preg Grep is a bit cleaner then array filter and a callback with a regular expression. I also realized you had a superficial loop in there $levels = array($assignedIDs); or basically $levels = array($level); or just $level.
Same output as before
Sandbox

how to remove array value from array when value not same from both the value [duplicate]

This question already has answers here:
How to Remove value from an array using another array with multiple values?
(4 answers)
Closed 4 years ago.
I have two array, and i want to remove duplicate record from array2. i don't want to link_id 35 record in array 2 because link_id 35 record is present in array1 so it's not show in array2.
I tried with array_map and Unique methods but it's not working well because i think both the array doesn't have the same value.
$array1=
[0] => stdClass Object
(
[link_id] => 35
[link_name] => Test Listerine cool mint packets 3 pack
[alias] => aa
[link_desc] =>
[user_id] => 47
[link_hits] => 103
[link_votes] => 1
[link_rating] => 5.000000
[link_featured] => 0
[link_published] => 1
[link_approved] => 1
[link_template] =>
)
[1] => stdClass Object
(
[link_id] => 373
[link_name] => Test Subject Data Collection Fish Fresh Yellow Tail
[alias] => ba
[link_desc] =>
[user_id] => 47
[link_hits] => 198
[link_votes] => 8
[link_rating] => 2.875000
[link_featured] => 0
[link_published] => 1
[link_approved] => 1
[link_template] =>
)
$array2 =
[0] => stdClass Object
(
[link_id] => 35
[link_name] => Test Listerine cool mint packets 3 pack
[link_desc] =>
[lat] => 0.000000
[lng] => 0.000000
[contactperson] =>
[cat_name] => AA - Made in USA
[link_votes] => 1
[link_rating] => 5.000000
[link_featured] => 0
[value] => 30020864
)
[1] => stdClass Object
(
[link_id] => 541
[link_name] => Test Subject Data Collection Fish Fresh Yellow Tail
[link_desc] =>
[lat] => 25.182573
[lng] => -80.093079
[country] => United States
[postcode] => 33431
[contactperson] => Captain Jack Certified Charters
[cat_name] => BA - Product of USA
[link_votes] => 8
[link_rating] => 2.875000
[link_featured] => 0
[value] => NA
)
You can do that with array-filter. First extract all the ids from the first array and then filter the second array based of those ids.
$arr1 = array( (object) ["link_id"=> 35, "key" => "AAA"], (object) ["link_id"=> 373, "key" => "BBB"]);
$arr2 = array( (object) ["link_id"=> 35, "key" => "CCC"], (object) ["link_id"=> 341, "key" => "DDD"]);
$ids = array_column($arr1, "link_id");
$arr2 = array_filter($arr2, function ($e) use ($ids) {
return !in_array($e->link_id, $ids); //keep him in arr2 only if NOT in ids of arr1
});
Updated more fast answer Consider big amount of data (as for #mickmackusa comment) use this:
$ids = [];
foreach($arr1 as $e)
$ids[$e->link_id] = true;
$arr2 = array_filter($arr2, function ($e) use ($ids) {
return !isset($ids[$e->link_id]);
});
First solution is in O(n^2) and the second is in O(n)
This should do in php7.
Untested code:
var_export(array_diff_key(array_column($array2, null, 'link_id'), array_column($array1, null, 'link_id'));
Assign new 1st level keys to both arrays, then filter on those keys.
Checking against keys will be more efficient than making iterated calls of in_array.

php move keys from array into another array

So I have this array:
[0] => 3
[1] => 9
[2] => 4
[3] => 6
[4] => 69
[5] => 8
[6] => 9
[7] => 12
[8] => 9
[9] => 7
And this one
[Far] => 1
[far] => 3
[away] => 1
[behind] => 1
[the] => 23
[word] => 2
[mountains] => 1
[from] => 3
[countries] => 1
[Vokalia] => 1
I would like that the values of the first array will overwrite the values of the second array without changing the keys of the second array.
I have already tried fiddling with the foreach function, but no prevail.
So in the end I would like it to look like this:
[Far] => 3
[far] => 9
[away] => 4
[behind] => 6
[the] => 69
[word] => 8
[mountains] => 9
[from] => 12
[countries] => 9
[Vokalia] => 7
does anyone know how to do that? And if yes, can that person give a bit more information how it works in the foreach function?
Assuming your arrays are $array1 and $array2:
$keys = array_keys($array2);
$result = array_combine($keys, $array1);
Documentation:
array_keys()
array_combine()
Online demo

Categories