I'm actually running into an issue when trying to put this into practice. So, I have a list of goal ids and a current amount. I need to pass all these values which I am by doing goalidlist[] and current[]. The issue is when I'm running the foreach and doing the SQL Update per goalid. Here's my code below. Hope someone can point out what I'm doing wrong.
$goalidlist = $_POST['goalidlist'];
$currentnums = $_POST['current'];
if (isset($_POST['goalidlist'])) {
foreach($goalidlist as $key => $glist) {
// Update key goals
$updGoals = "UPDATE okr_3519031jkl.key_goals SET current=? WHERE goalid=? AND userid=?";
if ($stmt = mysqli_prepare($conn, $updGoals)) {
// Bind Params
mysqli_stmt_bind_param($stmt, "sii", $currentnums[$key], $glist, $userid);
mysqli_stmt_execute($stmt);
$stmt->close();
}
}
}
goalidlist[] = Array ( [0] => 4 [1] => 1 [2] => 2 [3] => 3 [4] => 5 [5] => 6 [6] => 9 [7] => 7 [8] => 8 [9] => 10 [10] => 11 [11] => 12 [12] => 13 )
current[] = Array ( [0] => 3 [1] => 1 [2] => 2 [3] => 6 [4] => 2 [5] => 12 [6] => 3 [7] => 1 [8] => 7 [9] => 9 [10] => 2 [11] => 6 [12] => 3 )
I've got a multidimensional array that I want to sort alphabetically by the values of specific key. Structure of the array is -
Array
(
[sr] => Array
(
[2] => 1
[3] => 2
[4] => 3
[5] => 4
[6] => 5
[7] => 6
[8] => 7
[9] => 8
[10] => 9
)
[deptt] => Array
(
[2] => KKT-TICKETING
[3] => KKT-TICKETING
[4] => KKT-TICKETING
[5] => KKT-HOTELS
[6] => KKT-TICKETING
[7] => KKT-HOTELS
[8] => GTT-TICKETING
[9] => GTT-HOTELS
[10] => GTT-TICKETING
)
I wanted to sort the data on basis of key 'deptt' alphabetically by the values. My desired output should be like all 'GTT-HOTELS' data should shown first then 'KKT-HOTELS' -
[deptt] => Array
(
[2] => GTT-HOTELS
[3] => GTT-TICKETING
[4] => GTT-TICKETING
[5] => KKT-HOTELS
[6] => KKT-HOTELS
[7] => KKT-TICKETING
[8] => KKT-TICKETING
[9] => KKT-TICKETING
[10] => KKT-TICKETING
)
with corresponding values of key 'sr'.
Any ideas how to do this? Hope I could make you understand the scenario.
Given this data:
$data = [
'sr' =>
[
2 => 1,
3 => 2,
4 => 3,
5 => 4,
6 => 5,
7 => 6,
8 => 7,
9 => 8,
10 => 9,
],
'deptt' =>
[
2 => 'KKT-TICKETING',
3 => 'KKT-TICKETING',
4 => 'KKT-TICKETING',
5 => 'KKT-HOTELS',
6 => 'KKT-TICKETING',
7 => 'KKT-HOTELS',
8 => 'GTT-TICKETING',
9 => 'GTT-HOTELS',
10 => 'GTT-TICKETING',
]
];
The below code can be used. The magic is in the array_combine function which merges two arrays, using one for the keys and one for the values. However, in both cases, it takes the values of those arrays, so you need to call array_keys on the former to get those as values.
// Grab our arrays as variables
$sr = $data['sr'];
$deptt = $data['deptt'];
// Sort the latter by values alphabetically
sort($deptt);
// Merge them together, keys from the first and values from the second
$final = array_combine(array_keys($sr), $deptt);
This produces the following:
array (
2 => 'GTT-HOTELS',
3 => 'GTT-TICKETING',
4 => 'GTT-TICKETING',
5 => 'KKT-HOTELS',
6 => 'KKT-HOTELS',
7 => 'KKT-TICKETING',
8 => 'KKT-TICKETING',
9 => 'KKT-TICKETING',
10 => 'KKT-TICKETING',
)
Additional care should be taken to make sure that both arrays have the same number of items. array_combine will return false in that case.
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){
}
I'm using larger arrays in my project, but to simplify, let's say we have this 3x3 array:
$a = Array( Array(1,2,3),
Array(4,5,6),
Array(7,8,9) );
I want to find every combination of sums that includes one value from each row, i.e., 1+4+7, 1+4+8, 1+4+9, 1+5+7, 1+5+8, 1+5+9, 1+6+7, 1+6+8, 1+6+9, 2+4+7, 2+4+8, 2+4+9, 2+5+7, ...
Hopefully the pattern is evident. I tried a nested loop first (columns, then rows), but that didn't provide all the combinations. After quite a bit of searching, I feel confident that the solution requires recursion, but every time I try to write a recursive function for this, I get confused.
While working code will be very much appreciated, what's perhaps more important to me is understanding the problem and the solution.
Given an unknown number of rows and columns in the array, the best way to get the result you want is to use recursion (otherwise you will have to write an arbitrary number of nested loops). This function recurses over each row in the array and returns one of two results:
If we're at the last row in the array, return that row;
Otherwise, return the cross product (using two nested foreach loops) between the current row and the result from the balance of the array. We use array_shift to both get the current row, and remove it from the array.
Here is the code:
function find_paths($array) {
if (count($array) == 1) return $array[0];
$output = array();
foreach (array_shift($array) as $v1) {
foreach (find_paths($array) as $v2) {
$output[] = array_merge(array($v1), is_array($v2) ? $v2 : array($v2));
}
}
return $output;
}
Using your example data:
$a = Array( Array(1,2,3),
Array(4,5,6),
Array(7,8,9) );
$combinations = find_paths($a);
The function does this series of operations:
take the cross product of row 1 (1, 2, 3) with the output of the function for the balance of the array ((4, 5, 6), (7, 8, 9));
First recursion: take the cross product of row 2 (4, 5, 6) with the output of the function for the balance of the array ((7, 8, 9));
Second recursion: At this point we only have one row remaining in the array (7, 8, 9), so we return it;
First recursion: Compute the cross product of (4, 5, 6) with (7, 8, 9) = ((4, 7), (4, 8), (4, 9), (5, 7), (5, 8), (5, 9), (6, 7), (6, 8), (6, 9)) and return that;
Take the cross product of (1, 2, 3) with ((4, 7), (4, 8), (4, 9), (5, 7), (5, 8), (5, 9), (6, 7), (6, 8), (6, 9)) and return that.
Giving an output of:
Array (
[0] => Array ( [0] => 1 [1] => 4 [2] => 7 )
[1] => Array ( [0] => 1 [1] => 4 [2] => 8 )
[2] => Array ( [0] => 1 [1] => 4 [2] => 9 )
[3] => Array ( [0] => 1 [1] => 5 [2] => 7 )
[4] => Array ( [0] => 1 [1] => 5 [2] => 8 )
[5] => Array ( [0] => 1 [1] => 5 [2] => 9 )
[6] => Array ( [0] => 1 [1] => 6 [2] => 7 )
[7] => Array ( [0] => 1 [1] => 6 [2] => 8 )
[8] => Array ( [0] => 1 [1] => 6 [2] => 9 )
[9] => Array ( [0] => 2 [1] => 4 [2] => 7 )
[10] => Array ( [0] => 2 [1] => 4 [2] => 8 )
[11] => Array ( [0] => 2 [1] => 4 [2] => 9 )
[12] => Array ( [0] => 2 [1] => 5 [2] => 7 )
[13] => Array ( [0] => 2 [1] => 5 [2] => 8 )
[14] => Array ( [0] => 2 [1] => 5 [2] => 9 )
[15] => Array ( [0] => 2 [1] => 6 [2] => 7 )
[16] => Array ( [0] => 2 [1] => 6 [2] => 8 )
[17] => Array ( [0] => 2 [1] => 6 [2] => 9 )
[18] => Array ( [0] => 3 [1] => 4 [2] => 7 )
[19] => Array ( [0] => 3 [1] => 4 [2] => 8 )
[20] => Array ( [0] => 3 [1] => 4 [2] => 9 )
[21] => Array ( [0] => 3 [1] => 5 [2] => 7 )
[22] => Array ( [0] => 3 [1] => 5 [2] => 8 )
[23] => Array ( [0] => 3 [1] => 5 [2] => 9 )
[24] => Array ( [0] => 3 [1] => 6 [2] => 7 )
[25] => Array ( [0] => 3 [1] => 6 [2] => 8 )
[26] => Array ( [0] => 3 [1] => 6 [2] => 9 )
)
If you then want to get the sums, you can simply use an array_map on the array, calling array_sum to get the sum of each element:
$sums = array_map(function ($v) { return array_sum($v);}, $combinations);
Output:
Array (
[0] => 12
[1] => 13
[2] => 14
[3] => 13
[4] => 14
[5] => 15
[6] => 14
[7] => 15
[8] => 16
[9] => 13
[10] => 14
[11] => 15
[12] => 14
[13] => 15
[14] => 16
[15] => 15
[16] => 16
[17] => 17
[18] => 14
[19] => 15
[20] => 16
[21] => 15
[22] => 16
[23] => 17
[24] => 16
[25] => 17
[26] => 18
)
Demo on 3v4l.org
After tinkering with this for some time, I found another solution that's much faster and uses a lot less memory than either Nick's or my original answers. This becomes important when using larger and more numerous arrays. Instead of 3 by 3 (27 combinations), try 9 by 9 (134 million combinations), for example.
Nick still deserves the accepted answer for providing code that not only works as asked, but is well-explained. Also, this code borrows some of the logic from Nick's code.
The performance trick is that instead of finding all the combinations and then getting the sums, we only gets the sums. That way, we're not creating a potentially massive array of arrays, but just one potentially massive array.
Edit: Passing $sums by reference instead of using array_merge saves significantly more time and memory. Code updated.
function combo_sums($arrays, $sum = 0, &$sums = []) {
$array = array_shift($arrays);
if (count($arrays) > 0)
foreach ($array as $value)
combo_sums($arrays, $sum + $value, $sums);
else
foreach ($array as $value)
$sums[] = $sum + $value; # These are the final sums.
return $sums;
}
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