find id of post with highest value - php

I have an array of posts that I want to sort - but before I do, I want to find the id of the post with the highest number of likes.
I loop through the array using a foreach. Although it seems like a waste to do two foreach loops for this - I don't know if there's an alternative when trying to find the highest value beforehand?
Array
(
[0] => Array
(
[id] => 162
[like_count] => 2
etc.
)
[1] => Array
(
[id] => 165
[like_count] => 23
etc.
)
)
So the second post has the highest amount of likes, so I need the ID of 165 - then when I loop through I can do something like
foreach ($posts as $post){
if($most_liked_id == $post["id"]){
// this post is the most liked!
}
}
Any help would be much appreciated - thanks!

$highest = 0;
$highest_id = 0;
foreach($array as $a) {
if($a['like_count'] > $highest) {
$highest = $a['like_count'];
$highest_id = $a['id'];
}
}
Hope I understood you correctly :)

This looks like data retrieved from a database. If so, use the ORDER BY like_count DESC clause in the SQL.
The ID of the post with the most likes will then be at $posts[0]['id'] before you sort by your other method.

very easy task, you loop through your posts.
function get_max_like_post($posts) {
$max_like = 0;
$max_like_post = array();
foreach ($posts as $post) {
if ($post['like_count'] > $max_like) {
$max_like = $post['like_count'];
$max_like_post = $post;
}
}
return $max_like_post['id']
}

You could use usort.
$posts = array(
array('id' => 161, 'like_count' => 0),
array('id' => 162, 'like_count' => 6),
array('id' => 4, 'like_count' => 2),
);
function like_sort($a, $b) {
if ($a['like_count'] == $b['like_count']) {
return 0;
}
return ($a['like_count'] > $b['like_count']) ? -1 : 1;
}
usort($posts, 'like_sort');
// The first element in the array is now the one with the highest like_count.
echo $posts[0]['id']; // 162

Try this:
usort($posts, function($item) { return -$item['like_count']; });
$id = empty($posts) ? null : $posts[0]['id'];
Where $posts is the input array.
Explanation:
first you sort the posts by like count in decreasing fashion
then you get the top post id if there any posts, null otherwise.
What's good about this solution is that you can also select first n posts.

$highest_post_likes = 0;
$highest_post_id = 0;
for($i = 0; $i < sizeof($posts); $i++) {
if ( $posts[$i][like_count] > $highest_post_likes ) {
$highest_post_likes = $posts[$i][like_count];
$highest_post_id = $i;
}
}
// now you can use $posts[$highest_post_id]

Is those datas came from a database like MySQL? If is it, the simpliest solution is to put an "ORDER BY".
You can also make seperate the 'like_count' array keeping the same key than your first array and doing a asort (http://www.php.net/manual/fr/function.asort.php). You will have the key of the highest like count.

You can sort the array in descending order based on like_count and then pick up the id for the first array element.

You can use max function to get the highest value of likes:
foreach ($posts as $post){
$max[]=$post['like_count'];
}
echo max($max['id']);

Related

foreach loop multidimensional array but only loop through array elements with specific key

I am creating following array that contains all products and all their categories:
$result = $wpdb->get_results("SELECT product_nr, category FROM erp_product_categories",ARRAY_A);
$product_categories = array();
foreach($result as $row){
$product_categories[$row["product_nr"]][] = $row["category"];
}
(product_nr is an integer and category is a string)
Then i want to check if one of the categories of a product matches with an other variable and return true if thats the case:
foreach($product_categories[$ean] as $product_categorie) {
$manages_post = in_array( $product_categorie, $this->term_link_conditions );
if($manages_post == true){
break;
}
}
return $manages_post;
But I am getting the error
Invalid argument supplied for foreach()
is it not possible to loop only through elements of an array with a specific key?
Edit:
The array looks like this
Array
(
[10001] => Array //product_nr
(
[0] => 1 //category
[1] => 4 //category
)
[10002] => Array
(
[0] => 1
[1] => 20
)
//...
)
You should check that what you are passing to foreach is an array by using the is_array function
If you are not sure it's going to be an array you can always check using the following PHP example code:
if (is_array($product_categories[$ean])) {
foreach ($product_categories[$ean] as $product_categorie) {
//do something
}
}
Check out all your foreach statements, and look if the thing before the as, to make sure it is actually an array. Usevar_dump to dump it.
Try this :
if(is_array($product_categories) && sizeof($product_categories) > 0) {
foreach($product_categories as $key => $product_categorie) {
if($manages_post = in_array($key, $this->term_link_conditions)){
return $manages_post;
}
}
}
I figured out a way to do this
$product_category = $product_categories[$ean];
if (is_array($product_category)) {
$matches = array_intersect($product_category, $this->term_link_conditions);
if(sizeof($matches) > 0){
$manages_post = true;
}
}

post an array and iterate throught it in PHP codeigniter

This is the first time i create my own webservice (someone always did it for me before), so please bear with me.
I post this array :
$data = array(
'user_id' => $this->post('user_id'),
'group_id' => $this->post('group_id'),
'child_id' => $this->post('child_id'), //will be nested array
'custom' => $this->post('custom'),
'time' => $this->post('time'),
'date' => $this->post('date')
);
I tried to create a nested array with this : $this->post('child_id'), because user can post multiple child_id at once.
Then i tried to iterate through the child_id, because i need to insert them to the mysql :
for($i = 0; $i < sizeof($data['child_id']); $i++)
{
$result2 = $this->schedule_m->add_trans('transaction_schedule', $data, $result_id[0]['id']);
}
What should i do, so i can have an array of child_id in my $data array? (nested array)
And how to iterate through it?
UPDATE :
I have updated the codes above.
I use advanced rest client for testing, and i tried to post something like this in the form content type :
child_id=1&user_id=1&group_id=1&custom=&time=17%3A17%3A00&date=&child_id=2
Notice that theres two child_id (left most and right most), but only the last one (right most) is inserted.
And this is the add_trans in the model :
function add_trans($table, $data, $schedule_id) {
$query = $this->db->insert($table, array('child_id' => $data['child_id'], 'schedule_id' => $schedule_id));
return $query;
}
Thanks a lot for your time.
Even thought you set the name attribute as child[] on the markup,
You still need to call it as:
'child_id' => $this->post('child_id')
It will still return an array.
for($i = 0; $i < sizeof($data['child_id']); $i++) {
$result2 = $this->schedule_m->add_trans('transaction_schedule', $data, $result_id[0]['id']);
}
EDIT:
Looking upon you query string, that seems to be the culprit:
child_id=1&user_id=1&group_id=1&custom=&time=17%3A17%3A00&date=&child_id=2
^ same index , same index, same index, it will overwrite and you will get only `2`
If you want to get them all into an array format, you need to set them like this
child_id[]=1&user_id=1&group_id=1&custom=&time=17%3A17%3A00&date=&child_id[]=2
^ it needs to be set like this
UPDATE:
And in your model, if you want each id per row, well you can also loop in this case:
function add_trans($table, $data, $schedule_id) {
foreach($data['child_id'] as $child_id) {
$query = $this->db->insert($table, array('child_id' => $child_id, 'schedule_id' => $schedule_id));
}
// return $this->db->insert_id();
return $query;
}
ofcourse that won't work, it has to be
for($i = 0; $i < sizeof($data['child_id']); $i++)
{
$result2 = $this->schedule_m->add_trans('transaction_schedule', $data['child_id'][$i], $result_id[0]['id']);
}
because you've not set $data['child_id[]'] so it doesn't exist, the key is just a string or number, it does not validate or parse anything
you don't need to give child[] in post method. just give only child, it will get complete array what are you sending from views
replace
'child_id' => $this->post('child_id[]')
with
'child_id' => $this->post('child_id')

PHP Combining arrays after foreach

i have products that belong to categories and i need to get such categories and output them as a single array. This is my this code:
$act_prod = array(0=>1,1=>10);
$active_cat = array();
foreach ($act_prod as $act) {
$cat = $this->getDi()->productTable->load($act);
$active_cat[$act] = $cat->getCategories();
}
print_r($active_cat);
Which will output:
Array ( [1] => Array ( [0] => 1 ) [10] => Array ( [0] => 2 ) )
This means product 1 belongs to category 1 and product 10 to category 2 but i dont need all that. I only need the categories like this: Array (1, 2) or Array (0=>1, 1=>2).
What should i use so i get the correct output?
Thank you.
Modified your code to build up just the list you want.
$act_prod = array(0=>1,1=>10);
$active_cat = array(); // will be a flat list of categories
foreach ($act_prod as $act) {
$cat = $this->getDi()->productTable->load($act);
foreach($cat->getCategories as $category) {
// if we have not seen this category on any previous category, push it
if(!in_array($cat->getCategories(), $active_cat)) {
array_push($active_cat, $cat->getCategories());
}
}
}
// if desired, sort array first
print_r($active_cat);
foreach ($act_prod as $act) {
$cat = $this->getDi()->productTable->load($act);
$cats = $cat->getCategories();
foreach($cats as $cat)
{
$active_cat[] = $cat['cat_id'];
}
}
Assuming cat_id is your category id
You need to flatten the $active_cat array, like this:
// ...
foreach ($cat->getCategories() as $category) {
$active_cat[] = $category;
}
// ...
Afterwards, make sure there are no duplicates:
$active_cat = array_unique($active_cat);

Array Combine in PHP

I am trying to combine keys and values in arrays. I have an product_id with different price.
Let say
Product id and price
id 101 and price is 100
id 105 and price is 200
id 101 and price is 300
list of product ids in array with $product_ids[] and list of price also $price_amount[]
So I preferred to combine the two arrays using array_combine
I made array_combine($product_ids,$price_amount);
Now it appears look like this way
array(2) { [101]=> float(100) [105]=> float(300) }
Is there is a way to add the key elements to the id as something like
array(2) {
[101] => float(400) (100+300)
[105] => float(300)
}
Here is the idea i tried
$products = array();
$order_totalss = array();
foreach (get_posts('post_type=shop_order&numberposts=-1&post_status=publish') as $order) {
$order = new WC_Order($order->ID);
if (wc_customer_bought_product($order->billing_email, $order->user_id, $product_id)) {
$productcounts[] = $product_id;
$order_totalss[] = $order->get_total();
}
}
$arraymergeme = array_combine($productcounts, $order_totalss);
You will have to do this manually I'm afraid:
$total = array();
foreach ($product_ids as $key => $value) {
// each value of product_ids becomes the key
if (isset($total[$value])) {
// we have seen this key before
$total[$value] += $price_amount[$key];
} else {
// new key
$total[$value] = $price_amount[$key];
}
}
Simple code so you can see what's happening clearly:
$ids = array(101, 105, 101);
$prices = array(100, 200, 300);
$totals = array();
foreach ($ids as $key => $id)
{
// Make sure index is defined
if ( ! isset($totals[$id]))
{
// Make sure we have a value
$totals[$id] = 0;
}
// Assuming index $key matches... add to the total
$totals[$id] += $prices[$key];
}
PHP arrays are associative so you can write something like: price['101'] = 100 thereby using the product id as the array index.
Thinking you are looking for something like this. I haven't done php in awhile, so the syntax may need tweaking, but I think the logic is correct.
$cart = array(
"101" => 100,
"105" => 200,
"101" => 300
);
$product_id_arr = array();
foreach ($cart as $product_id => $price) {
if(array_key_exists($product_id, $product_id_arr)){
$product_id_arr[$product_id] = $product_id_arr[$product_id] + $price;
}else{
$product_id_arr[$product_id] = $price;
}
}
array_combine will not do the trick for you. You will have to iterate through the array and total them as you go. Here's an example:
<?php
$product_ids = array('101', '105', '101');
$price_amount = array(100, 200, 300);
$combined = array();
$productCount = count($product_ids);
for($i = 0; $i < $productCount; $i++) {
// if this product_id is not in the $combined array, add its price
// as associative array ('101'=>100)
// but if it is found in $combined, add to its current price
if (!array_key_exists($product_ids[$i], $combined)) {
$combined[$product_ids[$i]] = $price_amount[$i];
} else {
$combined[$product_ids[$i]] += $price_amount[$i];
}
}
print_r($combined);
?>
Results:
Array
(
[101] => 400
[105] => 200
)
Try this
$final_arr = array();
for($i=0;$i<count($product_ids);$i++) {
if(!isset($final_arr[$product_ids[$i]])) {
$final_arr[$product_ids[$i]] = 0;
}
$final_arr[$product_ids[$i]] += $price_amount[$i];
}
Yes you can add key elements to id, basically an array can be created by using the array() language construct. It takes any number of comma-separated key => value pairs as arguments.
array(
key => value,
key2 => value2,
key3 => value3,
...
)
the one you are looking for is associative array. you can definitely specify the key you want and store the value you want at that key.
here is a link that would be helpful

PHP MySQL building a 3 Tier multi dimensional array

So I have my query, its returning results as expect all is swell, except today my designer through in a wrench. Which seems to be throwing me off my game a bit, maybe its cause Im to tired who knows, anyway..
I am to create a 3 tier array
primary category, sub category (which can have multiples per primary), and the item list per sub category which could be 1 to 100 items.
I've tried foreach, while, for loops. All typically starting with $final = array(); then the loop below that.
trying to build arrays like:
$final[$row['primary]][$row['sub']][] = $row['item]
$final[$row['primary]][$row['sub']] = $row['item]
I've tried defining them each as there own array to use array_push() on. And various other tactics and I am failing horribly. I need a fresh minded person to help me out here. From what type of loop would best suit my need to how I can construct my array(s) to build out according to plan.
The Desired outcome would be
array(
primary = array
(
sub = array
(
itemA,
itemB,
itemC
),
sub = array
(
itemA,
itemB,
itemC
),
),
primary = array
(
sub = array
(
itemA,
itemB,
itemC
),
sub = array
(
itemA,
itemB,
itemC
),
),
)
Something like this during treatment of your request :
if (!array_key_exists($row['primary'], $final)) {
$final[$row['primary']] = array();
}
if (!array_key_exists($row['sub'], $final[$row['primary']])) {
$final[$row['primary']][$row['sub']] = array();
}
$final[$row['primary']][$row['sub']][] = $row['item'];
Something like this....
$final =
array(
'Primary1'=>array(
'Sub1'=>array("Item1", "Item2"),
'Sub2'=>array("Item3", "Item4")
),
'Primary2'=>array(
'Sub3'=>array("Item5", "Item6"),
'Sub4'=>array("Item7", "Item8")
),
);
You can do it using array_push but it's not that easy since you really want an associative array and array_push doesn't work well with keys. You could certainly use it to add items to your sub-elements
array_push($final['Primary1']['Sub1'], "Some New Item");
If I understand you correctly, you want to fetch a couple of db relations into an PHP Array.
This is some example code how you can resolve that:
<?php
$output = array();
$i = 0;
// DB Query
while($categories) { // $categories is an db result
$output[$i] = $categories;
$ii = 0;
// DB Query
while($subcategories) { // $subcategories is an db result
$output[$i]['subcategories'][$ii] = $subcategories;
$iii = 0;
// DB Query
while($items) { // $items is an db result
$output[$i]['subcategories'][$ii]['items'][$iii] = $items;
$iii++;
}
$ii++;
}
$i++;
}
print_r($output);
?>

Categories