How to check index exist or not in my array - php

I have two arrays
one show all the quiz. another one shows the all taken quiz. now I like o show this for each array that where all quiz list neet to show but match the done quiz table, if available it will return status true. I am using array_key_exist but its showing error.
$getquizId = [
'id' => '',
'title' => '',
'status' => ''
];
$allquizId = [];
$totalQuiz = Quize::where('course_id', $course_id)->with('resources')->get();
$doneQuiz = QuizProgress::where('user_id', $user_id)->where('course_id', $course_id)->with('course')->get();
$progress = (count($doneQuiz) / count($totalQuiz)) * 100;
foreach ($totalQuiz as $key => $value) {
$getquizId = [
'id' => $value->id,
'title' => $value->title,
'status' => (array_key_exists($key, $doneQuiz) ? ($value->id == $doneQuiz[$key]['id'] ? true : false) : false)
];
// if (array_key_exists($key, $doneQuiz)) {
// ($value->id == $doneQuiz[$key]['quiz_id'] ? $getquizId['status'] = 'true' : $getquizId['status'] = 'false');
// }
array_push($allquizId, $getquizId);
}
return $allquizId;
In here (array_key_exists($key, $doneQuiz) ? ($value->id == $doneQuiz[$key]['id'] ? true : false) : false) I need to check the array key exist o not.
I want to show the array like this
[
{
"id": 4,
"title": "Digital Marketing",
"status": true
},
{
"id": 5,
"title": "Personal Leadership",
"status": false
}
]

First get the id of the quiz which is done, and then check the array with in_array
But I would suggest you make the proper relationship
$doneQuiz = QuizProgress::where('user_id', $user_id)->where('course_id', $course_id)->with('course')->pluck('quiz_id')->toArray();
$getquizId = [
'id' => $value->id,
'title' => $value->title,
'status' => in_array($value->id, $doneQuiz) ? true : false
];

Dear always try to do some proper code.
$bool = false;
if(isset($doneQuiz[$key]['id']) && $value->id === $doneQuiz[$key]['id'] )
$bool = true;
put above code before $getquizId array and add $bool variable in value of status.
Note: check the $doneQuiz getting in array format.

Related

Get key value from multidimensional array not working

I am trying to get a value from a multidimensional array by its name 'code'. When I dump and die the first way it returns the correct value. When I then want to use that in the code, it gives the error "Undefined index: code". I also used the array_column way, that dd an empty array.
The code that should get the correct $code:
foreach ($houses as $house) {
$code = $house['code']; //Returns correct value in a dd, not in the code
$code = array_column($house, 'code'); //Returns empty array in dd, later gives the error Array to string conversion in the file_get_contents
$a = file_get_contents('some-url' . $code . '/surveys');
$a = json_decode($a, true);
$surveys = $a['surveys'];
$completedSurveys = $a['surveysCompleted'];
$done = 0;
$ndone = 0;
foreach ($completedSurveys as $complete) {
if($complete) {
$done++;
} else if(!$complete) {
$ndone++;
} else {continue;}
}
}
$house dump:
array:30 [
id: ''
project: integer
city: ''
streetName: ''
houseNumber: ''
code: ''
fullStreet: ''
forms: array:1 [
0: integer
]
]
$code dump
$house['code']: "AB12-CD34-EF56-GH78"
array_column($house, 'code'): []
I would like to know the solution to this so that I can use the $code in the url to get the correct things back from the api.
You can use array_column on your entire array, not the sub-arrays.
$houses =
[
[
'code' => '23',
'city' => 'Dublin'
],
[
'city' => 'Canberra'
],
[
'code' => '47',
'city' => 'Amsterdam'
]
];
var_export(array_column($houses, 'code'));
Output:
array (
0 => '23',
1 => '47',
)
You could then do something along these lines.
$get_survey = function ($code) {
if($response = file_get_contents("http://example.com/$code/surveys"))
if($json = json_decode($response, true))
return $json;
};
$completed = [];
foreach(array_column($houses, 'code') as $code) {
if($survey = $get_survey($code)) {
// survey count calculation.
} else {
$completed[$code] = null; // failure to get survey data.
}
}

2D array - search by value and return index of array

I've an array like
protected $aPermissions = [
'read' => [
'show'
],
'update' => [
'edit',
'editProfilePicture'
]
];
and I want to get the array key for the sub-array ('read', 'update') by a value to possibly find within the sub-array. So searching for 'edit' would return 'update', whereas 'show' would return 'read'.
I tried PHP's array_search function (also recursively, in a loop), but didn't manage to get this to work. What's the best approach to achieve what I want?
One option is using array_filter to loop thru the array and only include sub array that contains the $search string. Use array_keys to extract the keys.
$aPermissions = [
'read' => [
'show'
],
'update' => [
'edit',
'editProfilePicture'
]
];
$search = 'edit';
$result = array_keys(array_filter($aPermissions, function( $o ) use ( $search ) {
return in_array( $search, $o );
}));
$result will result to:
Array
(
[0] => update
)
Assuming that the keys are on the first level and the values are in the second level you could do something like this:
$innerKeys = [
"show",
"edit"
];
$output = [];
foreach ($array as $key => $value) {
if (is_array($value)) {
foreach ($value as $innerKey => $innerValue) {
if (isset($innerKeys[$innerKey])) $output[$innerKey] = $key;
}
}
}
If your problem is more complex, then you will need to give us additional information.
You can use array_walk and in_array to get the key, there is no return type array it's just simple key name else null
$aPermissions = [
'read' => [
'show'
],
'update' => [
'edit',
'editProfilePicture'
]
];
$searchAction = 'show';
$keyFound = '';
array_walk($aPermissions, function($value, $key) use ($searchAction, &$keyFound){
in_array($searchAction, $value) ? ($keyFound = $key) : '';
});
echo $keyFound;
Output
read
Look time not used PHP, but this code should work!!
<?php
$a = [
'read' => [
'show'
],
'update' => [
'edit',
'editProfilePicture'
]
];
$tmp = array_keys($a);
$searchterm = 'edit';
for($x =0 ; $x < count($tmp); $x++){
if(in_array($searchterm,$a[$tmp[$x]])){
echo $tmp[$x];
}
}

How to transform many array to 1 standard?

i have many api service with response
[
'brand_name' => Adidas,
'item_count' => 24
]
and
[
'brand_name' => Nike,
'count_item' => 254
]
and
[
'name' => Reebok,
'count_all' => 342
]
how to transform it to 1 standard? oop please
['brand' => $value, 'cnt' = $count]
If they are in the same order, just combine your keys with the values:
$array = array_combine(['brand', 'cnt'], array_values($array));
If not, just match and replace:
$array = array_combine(
preg_replace(['/.*name.*/', '/.*count.*/'], ['brand', 'cnt'], array_keys($array)),
$array);
If it could be brand, name or brand_name, etc. Then use an OR |:
/.*(name|brand).*/
If you know all of the possible combinations, then:
$replace = ['brand_name' => 'brand', 'name' => 'brand',
'item_count' => 'cnt', 'count_item' => 'cnt', 'count_all' => 'cnt'];
$array = array_combine(str_replace(array_keys($replace), $replace, array_keys($array)),
$array);
One of these should get you on the right path.
To transform many array into one standard like above, you need to think of common criteria that can apply to all arrays. In your case, I can see that all arrays have 2 keys, with the first keys contain a word "name" so I can use it as a criterion for "brand". Then there is second keys contain a word "count" used as a criterion for "cnt".
$new_array = [];
foreach($array as $item) {
$brand = '';
$cnt = '';
foreach($item as $key => $value) {
if(strpos($key, 'name') !== false) {
$brand = $value;
}
elseif(strpos($key, 'count') !== false) {
$cnt = $value;
}
// more conditions
}
$new_array[] = ['brand' => $brand, 'cnt' => $cnt];
}
Suppose you have another array:
[
'brand' => 'Danbo',
'total' => 200,
]
Since this is an exception, you need to make another condition:
elseif(strpos($key, 'brand') !== false) {
$brand = $value;
}
elseif(strpos($key, 'total') !== false) {
$cnt = $value;
}
or append to existing conditions:
if(strpos($key, 'name') !== false || strpos($key, 'brand') !== false) {
$brand = $value;
}
elseif(strpos($key, 'count') !== false || strpos($key, 'total') !== false) {
$cnt = $value;
}

How to detect the empty value or unset key in array?

$requiredKey = ['name', 'type', 'costPrice', 'salePrice'];
$newArr = ["costPrice" => "45",
"name" => "133",
"productType" => "456",
"remark" => "4545",
"salePrice" => "454545",
"saleType" => "789"];
foreach ($requiredKey as $key) {
if($newArr[$key] == null) {
//Why this place always is true?
echo 'null';
return false;
}
$insertData[$key] = $newArr[$key];
}
Those code used to detect the value is unset or empty, and sometime the value of key is not empty, but it always return true?
isset will do in most cases, array_key_exists is more "accurate" as it will detect also null values set (as opposed to not set at all.
isset($a['x']) --> false
array_key_exist('x', $a) --> false
$a['x'] = 1;
isset($a['x']) --> true
array_key_exist('x', $a) --> true
$a['x'] = null;
isset($a['x']) --> false
array_key_exist('x', $a) --> true
You can use empty instead.
$requiredKey = ['name', 'type', 'costPrice', 'salePrice'];
$newArr = ["costPrice" => "45",
"name" => "133",
"productType" => "456",
"remark" => "4545",
"salePrice" => "454545",
"saleType" => "789"];
foreach ($requiredKey as $key) {
if(empty($newArr[$key])) {
echo 'null';
return false;
}
$insertData[$key] = $newArr[$key];
}
empty will return true if array key doesn't exists or array key exists with null value.

Comparing two arrays in PHP foreach

What's the best way to compare both two arrays to each other in a foreach loop ?
I have two arrays, which one holds a boolean values and other one represents the real values.
First one of the arrays is some sort of configuration file where I tell what field is a required one TRUE or an optional FALSE:
$rules = array(
'fieldname1' => TRUE,
'fieldname2' => FALSE,
'fieldname3' => TRUE,
'fieldname4' => TRUE,
'fieldname5' => FALSE,
'fieldname6' => FALSE,
'fieldname7' => TRUE,
'fieldname8' => TRUE
);
And the other array which holds incoming data to be worked out:
$fields = array(
'fieldname1' => 'some value',
'fieldname3' => 'some value',
'fieldname4' => 'some value',
'fieldname7' => 'some value',
'fieldname8' => 'some value'
);
How do I make a check in foreach() loop, so the $fields array is going to compare each of its fieldnameX or (keys/indexes) with the other array named $rules ?
For example: $rules['fieldname1'] is required as it have a bool TRUE. So in foreach($fields as $field), the $field named fieldname1 should not be empty, null or false, if so, show an error.
This is a function I did so far which is not doing exactly what I want:
private function check_field_required_exist( $fields )
{
// Read rules from config to work with them accordingly
$rules = config_item('flow.format')[$fields['format']];
// Run throught the rules
foreach( array_keys($rules) as $field )
{
// Check wheter key existance is failed
if( !array_key_exists($field, $fields) )
{
// Checking failed, terminate the process
die('Required field: "'. $field .'" for requested format: "'.$fields['format'].'" does not exists.');
}
}
// Everything is alright
return TRUE;
}
// Goes through all the rules
foreach($rules as $key => $value)
{
// access all fields that are marked as required i.e key set as TRUE
if ($value)
{
//for those whose value is TRUE, check whether the corresponding field is set or
// whether it is empty (NULL,false)
if(!isset($fields[$key]) || empty($fields[$key]))
{
die('Required field does not exist');
}
}
}
foreach ($fields as $field => $value)
{
if (array_key_exists($field, $rules) && $rules[$field] === true)
{
if (!$value || $value == "" || $value === null)
{
die(); // return false;
}
}
}
return true;
I think that you can play around with the array functions in PHP. First thing I would do is to apply array_filter on your rules array. That way, you will only keep the TRUE values (and their indexes, since array_filter keep the index/value association).
Then I would use array_intersect_key to keep only the fields of interest in your fields var. And again array_filter with a custom callback to perform the verification you want to do.
$requiredField = array();
foreach($rules as $key=>$value) {
if($value == true && (!isset($fields[$key]) || $fields[$key] == "" )) {
$requiredField[] = $key;
}
}
if(count($requiredField) > 0) {
echo implode(',',$requiredField)." Are Required";
die;
}
USING PHP Array Functions:
$rules = array('name' => TRUE, 'phoneNumber' => TRUE, 'age' => FALSE);
$submittedFields = array( 'name' => 'aspirinemaga', 'age' => 38, 'phoneNumber' => '');
$requiredFields = array_keys(array_filter($rules));
$validFields = array_keys(array_filter($submittedFields));
$missingFields = array_diff($requiredFields, $validFields);
Given
$rules = array('name' => TRUE, 'phoneNumber' => TRUE, 'age' => FALSE);
$submittedFields = array( 'name' => 'aspirinemaga', 'age' => 38, 'phoneNumber' => '');
PhoneNumber is wrong here.
$requiredFields = array_keys(array_filter($rules));
This gives you the keys of all rule elements that are TRUE.
$validFields = array_keys(array_filter($submittedFields));
Same here, your definition of what's ok is the same as php truth table for boolean conversion. If you have a more advanced check, you could pass a function name into array_filter (see below).
$missingFields = array_diff($requiredFields, $validFields);
This will get you all the fieldNames that exist in $requiredFields but are not in $validFields.
More advanced validation
$rules = array('name' => 'MORE_THAN_3', 'phoneNumber' => TRUE, 'age' => 'POSITIVE');
$submittedFields = array( 'name' => 'aspirinemaga', 'age' => 38, 'phoneNumber' => '');
$requiredFields = array_keys(array_filter($rules));
function validateField($key, $value){
// get the rule (assuming no submittedFields that have no rule)
$rule = $rules[$key];
switch($rule){
case 'MORE_THAN_3': return strlen($value) > 3; break;
case 'POSITIVE': return $value > 0; break;
}
// in case of TRUE/FALSE
return TRUE;
}
$validFields = array_keys(array_filter("validateField", $submittedFields, ARRAY_FILTER_USE_BOTH));
$missingFields = array_diff($requiredFields, $validFields);
If you wanted to do a more advanced validation, you can integrate that nicely into above solution.
Say you wanted name to be more than 3 characters and age to be positive. Write it into your rules:
$rules = array('name' => 'MORE_THAN_3', 'phoneNumber' => TRUE, 'age' => 'POSITIVE');
$submittedFields = array( 'name' => 'aspirinemaga', 'age' => 38, 'phoneNumber' => '');
Required Fields are still the same (to check if one is missing).
$requiredFields = array_keys(array_filter($rules));
Now your validate function would be something like:
function validateField($key, $value){
// get the rule (assuming no submittedFields that have no rule)
$rule = $rules[$key];
switch($rule){
case 'MORE_THAN_3': return strlen($value) > 3; break;
case 'POSITIVE': return $value > 0; break;
}
// in case of TRUE/FALSE
return TRUE;
}
Pass that into array_filter and add to ARRAY_FILTER_USE_BOTH Flag:
$validFields = array_keys(array_filter("validateField", $submittedFields, ARRAY_FILTER_USE_BOTH));
And your missing Fields stays the same.
$missingFields = array_diff($requiredFields, $validFields);
This will only work in PHP 5.6+ (because ARRAY_FILTER_USE_BOTH). Not tested, should work.

Categories