I have a table that consists of comments. Some of them are replies to other comments and have a value set in parent_commentid table. I'm trying to create a function that checks each element in a result set if there is a value in the parent_columnid and if so take the entire element and sort it inside the element with a comment_id that matches the parent_commentid of the current element in the iteration. This is what I've come up with so far.
function sort_comments($comments){
$result = array();
foreach($comments as $comment){
if(is_null($comment['parent_commentid'])) $result[] = $comment;
else{
$parent_comment = array_search($comment['parent_commentid'], $comments);
if($parent_array !== false) $result[$parent_comment][] = $comment;
}
}
}
array_search is not the function I'm looking for but is the closets thing I could think of. Im not sure where to go from here. Keep in mind also that there can exist replies to other replies.
You need to store the comments by their own id, so that you can reference them later:
function sort_comments($comments){
$result = array();
foreach($comments as $comment){
if(is_null($comment['parent_commentid'])){
$result[$comment['commentid']] = $comment;
}else{
$parent_comment = $result[$comment['parent_commentid']]
if($parent_comment)
$parent_comment[$comment['commentid']] = $comment;
else
// what happens in this case:
// parent_commentid set, but no such comment exists?
}
}
Note the $comment['commentid']. I don't know how you call the id of a comment (commentid ?), but since you have a column parent_commandid you most likely do have such a column to reference your comments. Use that to store the comments, on top level or inside other comments.
To sort by internal fields of an array I usually use usort. Usort works as a recursive method so you can ensure that everytime you try to sort an element inside an array you will call your custom function. In this way you will get a more clean code.
Here is an example:
function cmp_rand_score($a, $b)
{
if($a["rand_score"] == $b["rand_score"]){
return 0;
}
return ($a["rand_score"] < $b["rand_score"]) ? 1 : -1;
}
//If you are inside a class:
usort($rows, array($this, "cmp_rand_score"));
//If not you can call directly:
usort($rows, "cmp_rand_score");
Hope it helps.
Related
I'm attempting to edit a custom function and struggling to get the row value for a particular custom column ('rank_td') to compare against its other columns (rank_lw and rank_lm), all inside a HTML table.
Tried a fair few variations and can't get it going.
Any ideas?
function custom_value($cellValue, $dataColumnHeader, $rank_td_value) {
if($dataColumnHeader == "rank_lw" || $dataColumnHeader == 'rank_lm'){
$row['rank_td']->$cellValue = $rank_td_value;
if($rank_td_value == $cellValue){
$styleColor = 'color:blue;';
}else if($rank_td_value < $cellValue){
$styleColor = 'color:green;';
}else{
$styleColor = 'color:red;';
}
return $class_name.'<span style="'.$styleColor.'">'.$cellValue.'</span>';
}
return $cellValue; }
You are not calling the global variable $row which exists outside the scope of this function - hence my comment that it doesn't look like it belongs here. If you want to be able to access a variable from outside a function you need to either pass that variable in, or declare it using the global keyword. Here is a very basic example of this:
$row['some_value'] = "value1";
function scopeTest($var1) {
$row['some_value'] = $var1;//local variable $row created
}
function scopeTestTwo($var1) {
global $row;//variable outside the function
$row['some_value'] = $var1;
}
scopeTest("jam");
print_r($row);//Array ( [some_value] => value1 )
scopeTestTwo("jam");
print_r($row);//Array ( [some_value] => jam )
in your code you also have this
return $class_name.'<span....
but $classname is not defined so either it is redundant and you should remove it (because this will cause a php notice and anyway redundant code is, well, redundant) or it should be defined somewhere which means something has been missed out
I have the following code which works perfectly fine to give me the name of the customer with the ID of 10:
foreach($customer_list as $row) {
if ($row->CUSTOMER_ID == 10)
echo $row->NAME;
}
Is there a way I can do this more directly, without the foreach loop and if statement? I'd like to do something like:
echo $customer_list[CUSTOMER_ID][10]->NAME;
But I don't know the syntax or if it's even possible.
You could use array_filter It will return an array of customers whose ID is 10. We then select the first match (the only match probably) and access the NAME property.
$name = reset( array_filter(
$customer_list,function($c){return $c->CUSTOMER_ID === 10;}
))->NAME;
The cleaner approach is to factor it out, into a separate function:
$getCustName = function($list,$id){
return reset( array_filter(
$list,
function($c) use ($id) {return $c->CUSTOMER_ID === $id;}
))->NAME;
};
Then you can get the name easily with just one line:
$name = $getCustName($customer_list,10);
You can use php array_filter method.
Basically you need to pass a function which will check value of customer_Id and returns the element of the array.
you can add your code inside a function and then call that function when you need the name. I am assuming you have unique customer ID's.
function getCustName($customers,$id){
if(count($customers)>0){
foreach($customers as $row) {
if ($row->CUSTOMER_ID == $id)
return $row->NAME;
}
} else{
return false;
}
}
Now if you need to get customer name just call the function
echo getCustName($customer_list,10);
Okay I'm new here and I have been trying to figure this out all day I have two functions one calling the other but my functions only returns the last value for example 29 when it should return multiple values. As wondering how can I fix this problem so that my functions return all the values.
Here is my PHP code.
function parent_comments(){
if(articles_parent_comments_info($_GET['article_id']) !== false){
foreach(articles_parent_comments_info($_GET['article_id']) as $comment_info){
$comment_id = filternum($comment_info['comment_id']);
reply_comment_count($comment_id);
}
}
}
function reply_comment_count($parent_id){
if(articles_reply_comments_info($_GET['article_id']) !== false){
foreach(articles_reply_comments_info($_GET['article_id']) as $reply_info){
$comment_id = filternum($reply_info['comment_id']);
$reply_id = filternum($reply_info['parent_id']);
if($parent_id === $reply_id){
reply_comment_count($comment_id);
}
}
}
return $comment_id;
}
You use recursivity to return your $comment_id. If I understand your needs, you want to get every reply id linked to one article id.
In reply_comment_count you return $comment_id but as it rescursively used and you don't keep the previous id returned you only get the last.
If you want to get numerous $comment_id instead of only one, I suggest you to return an array where you push $comment_id every time you find one. Something like that:
func parent_comments(){
loop in articles to get comment_id {
count_array = reply_comment_count(comment_id, count_array)
}
}
func reply_comment_count(parent_id, count_array) {
loop to get id linked to parent_id {
if id is an article {
count_array = reply_comment_count(id, count_array) #recursive call
}
else {
count_comment = count comment linked
count_array.push(count_comment)
}
}
return count_array # when you return your count_array due to recursive call it will be filled with every count, and not only the last
}
I hope this pseudo langage is clear for you. But as you only return the last count you found, you will only have this one.
I want to filter and delete an item from an array. is it possible to do it with array_filter() ?
//I want to delete these items from the $arr_codes
$id = 1223;
$pin = 35;
//Before
$arr_codes = Array('1598_9','1223_35','1245_3','1227_11', '1223_56');
//After
$arr_codes = Array('1598_9','1245_3','1227_11', '1223_56');
Thanks!
You can find the index of the value you are interested in with array_search and then unset it.
$i = array_search('1223_35',$arr_codes);
if($i !== false) unset($arr_codes[$i]);
array_filter does not take userdata (parameters). array_walk() does. However, none of the iterator function allow modifying the array structure within the callback.
As such, array_filter() is the appropriate function to use. However, since your comparison data is dynamic (per your comment), you're going to need another way to obtain comparison data. This could be a function, global variable, or build a quick class and set a property.
Here is an example using a function.
array_filter($arr, "my_callback");
function my_callback($val) {
return !in_array($val, get_dynamic_codes());
}
function get_dynamic_codes() {
// returns an array of bad codes, i.e. array('1223_35', '1234_56', ...)
}
Here's my code:
$quizId = '';
foreach ($module['QuizListing'] as $quizListing) {
if ($quizListing['id']) {
$quizId = $quizListing['id'];
break;
}
}
Is there a better way of doing this?
What you're doing is reasonable assuming that:
multiple quiz listings appear; and
not all of them have an ID.
I assume from your question that one of both of these is not true. If you want the first quiz listing then do this:
$listing = reset($module['quizListing']);
$quizId = $listing['id'];
The reset() function returns the first element in the array (or false if there isn't one).
This assumes every quiz listing has an ID. If that's not the case then you can't get much better than what you're doing.
Slight change:
$quizId = '';
foreach ($module['QuizListing'] as $quizListing) {
if (isset($quizListing['id'])) {
$quizId = $quizListing['id'];
break;
}
}
to answer if this array is coming from a database you probably have to better to filter your query not to include those row at first place
something like
SELECT * from Quiz WHERE id <> 0
this would give you an array usable without any other processing.
$quiz = array_shift($module['QuizListing']);
if (null != $quiz) {
echo "let's go";
}
Using array_key_exists you can check if the key exists for your array. If it exists, then assign it to whatever you want.
if (array_key_exists('id', $quizListing)) {
$quizId = $quizListing['id'];
}