So I have a couple of associated arrays of equal length and associations, and need to compare them. If the voted key in the first array has a value, I need to update the voted key value in the second array with that same value.
// create the arrays...
$votes_array = [];
array_push($votes_array, array(
'id' => '1',
'voted' => '-1'
)
);
array_push($votes_array, array(
'id' => '1',
'voted' => ''
)
);
$menu_array = [];
array_push($menu_array, array(
'id' => '1',
'voted' => ''
)
);
array_push($menu_array, array(
'id' => '1',
'voted' => ''
)
);
I tried this but but couldn't even get the result to echo true.
foreach ($votes_array as $votes_array_key => $votes_array_value) {
foreach ($menu_array as $menu_array_key => $menu_array_value) {
if( $votes_array_key == 'voted' && ($votes_array_value == '1' || $votes_array_value == '-1') ){
echo 'true';
// Update the $menu_array array index with the associated 'voted' value.
}
}
}
So it would end up with $menu_array[0]['voted'] being '-1'.
How do I achieve this?
Thanks.
Edit:
I've also modified the accepted answer to cater for when the length of votes_array varies.
foreach($votes_array as $votes_key => $votes_vote) {
if( ! $votes_vote['voted'] )
{
continue;
}
else
{
$getVoteId = $votes_array[$votes_key]['id'];
foreach($menu_array as $menu_key => $menu_vote)
{
if($menu_array[$menu_key]['id'] == $getVoteId)
$menu_array[$menu_key]['voted'] = $votes_vote['voted'];
}
}
}
Assuming those are strings and arrays are equal in length like you said this would be simple one from top of the head:
foreach($votes_array as $key => $vote) {
if( ! $vote['voted']) continue;
$menu_array[$key]['voted'] = $vote['voted'];
}
It seems you set your voted keys, so im using empty instead of isset to check for a non-value.
foreach($votes_array as $key=>$vote) {
if (!empty($vote["voted"])) {
$menu_array[$key]["voted"] = $vote["voted"];
}
}
Related
Array (
[category] => abc
[post_tag] => test
[nav_menu] => Home
[link_category] => Link 1
[post_format] => format
)
print conditional value from a loop in php
How can i check if a key is present in this loop
foreach($array as $ar)
{
if($ar->category == 'abc')
{
echo 'found';
}
}
I'm not quite sure what you're trying to find but if it's specific key/value pair it should look like this:
$array = Array (
'category' => 'abc',
'post_tag' => 'test',
'nav_menu' => 'Home',
'link_category' => 'Link 1',
'post_format' => 'format'
);
foreach($array as $key => $value) {
if ($key === 'category' && $value === 'abc') echo 'found', PHP_EOL;
}
Here you just have an associated array that doesn't have any nested arrays.
So if you want to do what you want on this array, you should do something like this:
if (isset($array['category']) && $array['category'] === 'abc') {
echo 'Found!';
}
Using null coalescing operator can make it easier:
if ($array['category'] ?? null === 'abc') {
echo 'Found!';
}
Your question isn't very clear. Do you want to check if a key on an array exists or check if the value exists inside the foreach?
I will try to answer both.
Given that we have this array:
$array = [
'category' => 'abc'
'post_tag' => 'test'
'nav_menu' => 'Home'
'link_category' => 'Link 1'
'post_format' => 'format'
];
If you want to check if a key exists in an array and print the keys value:
if(array_key_exists('category', $array){
echo $array['category']; // prints abc
}
more info about array_key_exists here: array_key_exists
If you want to check if a value exists in the array:
foreach($array as $ar){
if($ar === 'abc'){
echo $ar; // prints abc
}
}
In case you want to check for both of the above:
if(array_key_exists('category', $array) && $array['category'] === 'abc'){
echo $array['category']; // prints abc
}
I hope this helps you figure things out.
I have a multidimensional array and a variable to compare:
$var = 1;
$arr = array(
0 => array(
'id' => 5
'NumberAssigned' = 1
),
n => array(
'id' => 22
'NumberAssigned' = 1
)
)
I want to compare all of the value inside the NumberAssigned column in the multidimensional array with the variable, if all of the value in column match with the variable then $var = $var+1. What is the solution?
One option is using array_column to make the multidimensional array into a simple array. Use array_unique to get the unique values. If there are only 1 unique value and the value is the same with $var, all NumberAssigned are the same with $var
$var = 1;
$arr = array(
0 => array(
'id' => 5,
'NumberAssigned' => 1
),
1 => array(
'id' => 22,
'NumberAssigned' => 1
),
2 => array(
'id' => 23,
'NumberAssigned' => 1
),
);
$num = array_unique(array_column($arr,'NumberAssigned'));
if( count($num) === 1 && $num[0] === $var ) $var++;
No need to loop.
Use array_column to get all values and remove duplicates with array_unique.
If the var is in the array and the count is 1 then all values match var.
$narr = array_unique(array_column($arr, "NumberAssigned"));
If(in_array($var, $narr) && count($narr) == 1){
$var++;
}Else{
// They are not all 1
}
Echo $var;
https://3v4l.org/k08NI
You can force uniqueness by using the targeted column as first level keys. As a concise technique when you don't need microoptimization, you can use:
if (count(array_column($arr, null, 'NumberAssigned')) < 2)
// true if $arr is empty or all values in column are the same
This won't be technically fastest. The fastest algorithm would allow an early return before iterating the entire set of data in the column.
function allValuesAreSame($array, $columnName) {
$result = [];
foreach ($array as $row) {
$result[$row[$columnName]] = null;
if (count($result) > 1) {
return false;
}
}
return true; // also true if $array is empty
}
I have this array (see it below) and I want to repeat each array that has a key "repeat" with a value that represents how many times to repeat.
$fields = array(
array(
'type' => 'title-wrap',
'holder' => 'h4',
'heading' => 'Test heading',
),
array(
'repeat' => 3,
'type' => 'radio',
'name' => 'specific_name',
'value' => array(
0 => 'First', // value for first repeat
1 => 'Second', // value for second repeat
2 => 'Third' // value for third repeat
),
)
);
For that I have created a recursive function named generateForm:
function generateForm($fields, $index = 0) {
if ( $fields == '' ) { return false; }
foreach ($fields as $field) {
if ( isset($field['type']) ) {
switch ( $field['type'] ) {
case 'title-wrap':
echo $field['heading'];
break;
case 'radio':
echo $field['value'][$index];
break;
}
}
if ( isset($field['repeat']) ) {
for ($i=0; $i < $field['repeat']-1; $i++) {
generateForm($field, $i);
}
}
}
}
The output I want:
Test heading
First
Second
Third
But I don't get the last two words in the output. What am I doing wrong?
If you want to stick with the recursive method, then you need to correct some issues:
The recursive call you have does not pass an array, but an element of an array. Yet the function expects an array. So you should wrap it in an array construct when passing the first argument: [$field].
Once the above is fixed, the test on the repeat key will succeed again when you are in a recursive call, and so you will start that loop again, and get into an endless recursion. To prevent this from happening, don't loop, but just call the function recursively for the next repetition if there is at least one more to go.
Here is the corrected code:
function generateForm($fields, $index = 0) {
if ( $fields == '' ) { return false; }
foreach ($fields as $field) {
if ( isset($field['type']) ) {
switch ( $field['type'] ) {
case 'title-wrap':
echo $field['heading'] . "\n";
break;
case 'radio':
echo $field['value'][$index] . "\n";
break;
}
}
if ( isset($field['repeat']) && $index < $field['repeat'] - 1) {
generateForm([$field], $index + 1);
}
}
}
Ok, I have an array set up like so:
$buttons = array(
'home' => array(
'title' => $txt['home'],
'href' => $scripturl,
'show' => true,
'sub_buttons' => array(
),
'is_last' => $context['right_to_left'],
),
'help' => array(
'title' => $txt['help'],
'href' => $scripturl . '?action=help',
'show' => true,
'sub_buttons' => array(
),
),
);
Than I call a function after this is loaded to add some more buttons to it and have it sorted correctly, like this:
$buttons = load_dream_menu($buttons);
The load_dream_menu function looks like this:
function load_dream_menu($menu_buttons)
{
global $smcFunc, $user_info, $scripturl, $context;
$request = $smcFunc['db_query']('', '
SELECT *
FROM {db_prefix}dp_dream_menu
ORDER BY id_button ASC',
array(
)
);
$new_menu_buttons = array();
while ($row = $smcFunc['db_fetch_assoc']($request))
{
$permissions = explode(',', $row['permissions']);
$dp_temp_menu = array(
'title' => $row['name'],
'href' => ($row['target'] == 'forum' ? $scripturl : '') . $row['link'],
'show' => (array_intersect($user_info['groups'], $permissions)) && ($row['status'] == 'active' || (allowedTo('admin_forum') && $row['status'] == 'inactive')),
'target' => $row['target'],
'active_button' => false,
);
foreach ($menu_buttons as $area => $info)
{
if ($area == $row['parent'] && $row['position'] == 'before')
$new_menu_buttons[$row['slug']] = $dp_temp_menu;
$new_menu_buttons[$area] = $info;
if ($area == $row['parent'] && $row['position'] == 'after')
$new_menu_buttons[$row['slug']] = $dp_temp_menu;
if ($area == $row['parent'] && $row['position'] == 'child_of')
$new_menu_buttons[$row['parent']]['sub_buttons'][$row['slug']] = $dp_temp_menu;
if ($row['position'] == 'child_of' && isset($info['sub_buttons']) && array_key_exists($row['parent'], $info['sub_buttons']))
$new_menu_buttons[$area]['sub_buttons'][$row['parent']]['sub_buttons'][$row['slug']] = $dp_temp_menu;
}
}
if (!empty($new_menu_buttons))
$menu_buttons = $new_menu_buttons;
return $menu_buttons;
}
Ok, so it manages to sort the first one but doesn't sort the other one's after that? Is there something I'm supposed to use within the foreach loop of the load_dream_menu function? Something like using reset(), but that doesn't seem to work either. What am I doing wrong here? Please someone help me.
So basically, I check the database, than I loop through all available menu items and add them into another array, than at the end, I set the original array ($buttons) to the newly created array. Shouldn't this work? Here is where I do this within load_dream_menu() function:
foreach ($menu_buttons as $area => $info)
{
if ($area == $row['parent'] && $row['position'] == 'before')
$new_menu_buttons[$row['slug']] = $dp_temp_menu;
$new_menu_buttons[$area] = $info;
if ($area == $row['parent'] && $row['position'] == 'after')
$new_menu_buttons[$row['slug']] = $dp_temp_menu;
if ($area == $row['parent'] && $row['position'] == 'child_of')
$new_menu_buttons[$row['parent']]['sub_buttons'][$row['slug']] = $dp_temp_menu;
if ($row['position'] == 'child_of' && isset($info['sub_buttons']) && array_key_exists($row['parent'], $info['sub_buttons']))
$new_menu_buttons[$area]['sub_buttons'][$row['parent']]['sub_buttons'][$row['slug']] = $dp_temp_menu;
}
PHP does not have functions out of the box to insert elements after or before an indexed key.
The current problem with your function is that when you read the first row, you will put back all the previous menu buttons into the new menu buttons. After that, there is no way to insert before or after, short of rebuilding the array. I would suggest writing helper functions like
insert_before(array, key, value)
{
// Splice array in two at key, keeping key on the right side
// Append new value on the left tail
// Glue both arrays into a new array
// Return new array
}
insert_after(array, key, value)
{
// Symmetric with right & left switched
}
Then you can use those functions in your sorting routine.
I found this helpful post about efficient inserts in PHP arrays.
I hope this helps you.
I have a deep and long array (matrix). I only know the product ID.
How found way to product?
Sample an array of (but as I said, it can be very long and deep):
Array(
[apple] => Array(
[new] => Array(
[0] => Array([id] => 1)
[1] => Array([id] => 2))
[old] => Array(
[0] => Array([id] => 3)
[1] => Array([id] => 4))
)
)
I have id: 3, and i wish get this:
apple, old, 0
Thanks
You can use this baby:
function getById($id,$array,&$keys){
foreach($array as $key => $value){
if(is_array( $value )){
$result = getById($id,$value,$keys);
if($result == true){
$keys[] = $key;
return true;
}
}
else if($key == 'id' && $value == $id){
$keys[] = $key; // Optional, adds id to the result array
return true;
}
}
return false;
}
// USAGE:
$result_array = array();
getById( 3, $products, $result_array);
// RESULT (= $result_array)
Array
(
[0] => id
[1] => 0
[2] => old
[3] => apple
)
The function itself will return true on success and false on error, the data you want to have will be stored in the 3rd parameter.
You can use array_reverse(), link, to reverse the order and array_pop(), link, to remove the last item ('id')
Recursion is the answer for this type of problem. Though, if we can make certain assumptions about the structure of the array (i.e., 'id' always be a leaf node with no children) there's further optimizations possible:
<?php
$a = array(
'apple'=> array(
'new'=> array(array('id' => 1), array('id' => 2), array('id' => 5)),
'old'=> array(array('id' => 3), array('id' => 4, 'keyname' => 'keyvalue'))
),
);
// When true the complete path has been found.
$complete = false;
function get_path($a, $key, $value, &$path = null) {
global $complete;
// Initialize path array for first call
if (is_null($path)) $path = array();
foreach ($a as $k => $v) {
// Build current path being tested
array_push($path, $k);
// Check for key / value match
if ($k == $key && $v == $value) {
// Complete path found!
$complete= true;
// Remove last path
array_pop($path);
break;
} else if (is_array($v)) {
// **RECURSION** Step down into the next array
get_path($v, $key, $value, $path);
}
// When the complete path is found no need to continue loop iteration
if ($complete) break;
// Teardown current test path
array_pop($path);
}
return $path;
}
var_dump( get_path($a, 'id', 3) );
$complete = false;
var_dump( get_path($a, 'id', 2) );
$complete = false;
var_dump( get_path($a, 'id', 5) );
$complete = false;
var_dump( get_path($a, 'keyname', 'keyvalue') );
I tried this for my programming exercise.
<?php
$data = array(
'apple'=> array(
'new'=> array(array('id' => 1), array('id' => 2), array('id' => 5)),
'old'=> array(array('id' => 3), array('id' => 4))
),
);
####print_r($data);
function deepfind($data,$findfor,$depth = array() ){
foreach( $data as $key => $moredata ){
if( is_scalar($moredata) && $moredata == $findfor ){
return $depth;
} elseif( is_array($moredata) ){
$moredepth = $depth;
$moredepth[] = $key;
$isok = deepfind( $moredata, $findfor, $moredepth );
if( $isok !== false ){
return $isok;
}
}
}
return false;
}
$aaa = deepfind($data,3);
print_r($aaa);
If you create the array once and use it multiple times i would do it another way...
When building the initial array create another one
$id_to_info=array();
$id_to_info[1]=&array['apple']['new'][0];
$id_to_info[2]=&array['apple']['new'][2];