I am trying to remove pieces of a multidimensional array if a certain condition is met. The array can be as shown below, call it $friends:
array (size=3)
0 =>
array (size=1)
0 =>
object(stdClass)[500]
public 'id' => int 2
public 'first_name' => string 'Mary' (length=4)
public 'last_name' => string 'Sweet' (length=5)
1 =>
array (size=1)
0 =>
object(stdClass)[501]
public 'id' => int 9
public 'first_name' => string 'Joe' (length=3)
public 'last_name' => string 'Bob' (length=3)
2 =>
array (size=1)
0 =>
object(stdClass)[502]
public 'id' => int 1
public 'first_name' => string 'Shag' (length=4)
public 'last_name' => string 'Well' (length=4)
I have a function called is_followed, that let's me see if the id of one of the people in the array is being followed by the "user". The code I am trying is:
//remove followed friends from the $friends array
$i=0;
foreach($friends as $friend) {
foreach($friend as $f) {
if(Fanfollow::is_followed($id,$f->id)) {
unset($friend[$i]);
}
}
$i++;
}
The $id is the id of the current user.
However, this is not working. I know that using unset on $friend and not $friends is probably the issue. But using unset on $friends also won't work, because it is the higher level array. Any ideas? Thank you.
If you're trying to take down the first parent keys, use the first foreach keys instead:
foreach($friends as $i => $friend) {
// ^ assign a key
foreach($friend as $f) {
if(Fanfollow::is_followed($id,$f->id)) {
unset($friends[$i]);
// unset this
}
}
}
Or if only for that single friend:
foreach($friends as $friend) {
foreach($friend as $i => $f) {
// ^ this key
if(Fanfollow::is_followed($id,$f->id)) {
unset($friend[$i]);
// unset this
}
}
}
array_filter comes to the rescue:
array_filter($friend,
function($f) use($id) { return Fanfollow::is_followed($id,$f->id)); }
);
Though the solution with foreach is legit, array_filteris much more clear and sematically correct.
Related
I am trying to create and array to fill for my form_dropdown() for my view:
<?php echo form_dropdown('vendor', $vendors, '', 'class="form-control"') ?>
However, I am only getting the last value based on the function that generates the array:
public function get_vendors() {
$vendors = $this->db->table('vendor')->get()->getResultArray();
// Return key => value pair array
$array = array(
0 => 'Not Assigned'
);
if (!empty($vendors)) {
foreach ($vendors as $vendor) {
$array = array(
$vendor['id'] => $vendor['vendor']
);
}
}
return $array;
}
This function is within my model. The only problem I have is that it's returning only the last row from the table. However when I do a var_dump() for the $vendors I get all the rows. Not sure what I am doing wrong.
array (size=2)
0 =>
array (size=4)
'id' => string '1' (length=1)
'vendor' => string 'Blue Chip' (length=9)
'datecreated' => string '2022-08-16' (length=10)
'datemodified' => string '2022-08-16' (length=10)
1 =>
array (size=4)
'id' => string '2' (length=1)
'vendor' => string 'ASP' (length=3)
'datecreated' => string '2022-08-30' (length=10)
'datemodified' => string '2022-08-31' (length=10)
Changing the query to from getResultArray() to getResultObject() did the trick. So I was able to use $array[$vendor->id] = $vendor->vendor;
public function get_vendors() {
$vendors = $this->db->table('vendor')->get()->getResultObject();
// Return key => value pair array
$array = array(
0 => 'Not Assigned'
);
if (!empty($vendors)) {
foreach ($vendors as $vendor) {
$array[$vendor->id] = $vendor->vendor;
}
}
return $array;
}
If you still want to use getResultArray():
public function get_vendors() {
$vendors = $this->db->table('vendor')->get()->getResultArray();
// Return key => value pair array
$array = array(
0 => 'Not Assigned'
);
if (!empty($vendors)) {
foreach ($vendors as $vendor) {
$array[$vendor['id']] => $vendor['vendor'];
}
}
return $array;
}
I have an array that give objects back like this:
array (size=61)
0 =>
object(Xxx\Car)[602]
private 'id' => int 53
private 'name' => string 'Volkswagen' (length=10)
1 =>
object(Xxx\Car)[594]
private 'id' => int 43
private 'name' => string 'Toyota' (length=6)
2 =>
object(Xxx\Car)[595]
private 'id' => int 32
private 'name' => string 'BMW' (length=3)
How can I convert the array to so that the id become the key and the value the description, like this:
array (size=61)
53 => 'Volkswagen'
43 => 'Toyota'
32 => 'BMW'
I've tried
$cars = array();
foreach ($result as $key => $value) {
$cars[$value['id']] = $value['name'];
}
But that doesn't work.
You are treating your objects as if they were arrays.
$array['key'] is the notation for accessing an element in an array, but $object->key is the one for an object.
Try this :
$cars = array();
foreach ($result as $key => $value) {
$cars[$value->id] = $value->name;
}
EDIT : If that doesn't work (due to the private nature of the elements), you might have to declare functions like getID() and getName() in your object class file, and use them as such :
$cars = array();
foreach ($result as $key => $value) {
$cars[$value->getID()] = $value->getName();
}
Use the $arr = get_object_vars($obj); function. It converts an object to an array.
Hello i am trying to combine two php array.
First one
array (size=13)
0 =>
object(stdClass)[30]
public 'ID' => string '1' (length=1)
public 'name' => string 'html5' (length=5)
public 'img' => string 'HTML5.png' (length=9)
1 =>
object(stdClass)[31]
public 'ID' => string '2' (length=1)
public 'name' => string 'css3' (length=4)
public 'img' => string 'css.png' (length=7)
2 =>
object(stdClass)[32]
public 'ID' => string '3' (length=1)
public 'name' => string 'php' (length=3)
public 'img' => string 'php1.png' (length=8)
3 =>
object(stdClass)[33]
public 'ID' => string '4' (length=1)
public 'name' => string 'java script' (length=11)
public 'img' => string 'javascript.png' (length=14)
Second one
array (size=3)
0 =>
object(stdClass)[26]
public 'ID' => string '1' (length=1)
public 'IDuser' => string '1' (length=1)
public 'IDskill' => string '1' (length=1)
1 =>
object(stdClass)[27]
public 'ID' => string '2' (length=1)
public 'IDuser' => string '1' (length=1)
public 'IDskill' => string '3' (length=1)
2 =>
object(stdClass)[28]
public 'ID' => string '3' (length=1)
public 'IDuser' => string '1' (length=1)
public 'IDskill' => string '4' (length=1)
ID from first array is equal to IDskill from second array. I am trying to combine to create new array if IDskill and ID are same, with something like this in new array
public 'ID' => string '1' (length=1)
public 'name' => string 'html5' (length=5)
public 'img' => string 'HTML5.png' (length=9)
===>New field public 'MATCH' => string '1' (length=9)
use array_merge() function
<?php
$a1=array("red","green");
$a2=array("blue","yellow");
print_r(array_merge($a1,$a2));
?>
or
<?php
$fname=array("Peter","Ben","Joe");
$age=array("35","37","43");
$c=array_combine($fname,$age);
print_r($c);
?>
Try this ( where a1 is first array and a2 is second one and $result is final, merged array ):
$result = array();
$n=0;
foreach($a1 as $k=>$v) {
if (isset($v->ID) && isset($a2[$n]->ID) && $v->ID==$a2[$n]->ID) {
$result[$n]=$v;
$result[$n]->MATCH=1;
}
$n++;
}
print_r($result);
You could use array_map and anonymous functions:
<?php
$first_array = array(...);
$second_array = array(...);
// Anonymous function to extract the IDskills from the second array:
$get_IDs = function($element) {
return($element->IDskill);
};
// Array of (just) IDskills of the second array:
$IDs = array_map($get_IDs, array_filter($second_array, function($element) {
// Anonymous function to filter $second_array elements without IDskill:
return(isset($element->IDskill));
}));
// Another anonymous function that returns a new array with elements from
// $first_array with the new MATCH property.
// use(&$IDs) makes $IDs available inside the function scope:
$check_match = function($element) use(&$IDs) {
// We use clone because we don't want to modify the original array values:
$match_element = clone $element;
if(isset($match_element->ID))
$match_element->MATCH = in_array($match_element->ID, $IDs);
else
$match_element->MATCH = false;
return($match_element);
};
$match = array_map($check_match, $first_array);
?>
If you don't want to use the two first anonymous functions or don't want to create the $IDs array you can replace use(&$IDs) for use(&$second_array) and the line:
$match_element->MATCH = in_array($match_element->ID, $IDs);
for a loop that iterates through $second_array elements to check whether any of them has an IDskill equal to $match_element->ID.
Moreover, you may not need to check if IDskill and ID exist if all the elements in the arrays have the same properties.
let me add my two cents, how to find element matching ID from the 1st array in the second one
$tmp = array_filter($array2, function($ar2) use ($ID) { return $ar2->IDskill === $ID; });
if ($tmp) // Found
else // Not found
all code may be
result = array()
foreach ($array1 as $item) {
$ID = $item->ID;
$tmp = array_filter($array2, function($ar2) use ($ID) { return $ar2->IDskill === $ID; });
if ($tmp) { // Found
$tmp = $item;
$tmp->MATCH = 1;
result[] = $tmp;
}
}
So far my var_dump() of a $records array looks like:
array (size=1)
25 =>
array (size=1)
0 =>
object(stdClass)[51]
public 'id' => 25
public 'name' => info...
public 'surname' => info...
I wan't to change that 0 index name to object id (25) name but it just adds one more dimension above my current one. This is how I do it:
foreach ($records as $value) {
$records = array($value->id=>$records);
}
I want my array to look like this though:
array (size=1)
25 =>
object(stdClass)[51]
public 'id' => 25
public 'name' => info...
public 'surname' => info...
Updating keys so they equal the ID:
$tmp= array();
foreach ($records as $value) {
$tmp[$value->id] = $value;
}
$records = $tmp;
I've got the current array
array
161 =>
array
'cat_id' => string '5' (length=1)
'temp_id' => string '2' (length=1)
'prod_id' => string '44' (length=2)
162 =>
array
'cat_id' => string '3' (length=1)
'temp_id' => string '2' (length=1)
'prod_id' => string '44' (length=2)
164 =>
array
'cat_id' => string '2' (length=1)
'temp_id' => string '2' (lenth=1)
'prod_id' => string '45' (length=2)
I am using this function to remove the duplicate array values:
function removeDupes($array) {
$temp = array();
foreach ($array as $k => &$v) {
if (in_array($v['prod_id'],$temp)) {
unset($array[$k]);
}
$temp[] = $v['prod_id'];
}
return $array;
}
This removes any duplicate value in the array if prod_id is a duplicate in a previous array.
I'd like to maintain the full category id list for the product and at the moment, these get deleted when I unset the entire key=>value pair.
Has anyone got any ideas how I could achieve this?
EDIT as per comment:
I'm looking for something like this as a result:
array
161 =>
'cat_id' => array('5','3')
'prod_id' => 44
So I have removed the duplicate array entry that duplicated the product ID but maintained the Category ID's. I hope that helps.
Maybe something like this:
$input = array(); // define your array
$output = array(); // here will be output
$temp = array();
foreach($input as $key => $value)
{
if (isset($temp[$value['prod_id']]))
{
$output[$temp[$value['prod_id']]]['cat_id'][] = $value['cat_id'];
}
else
{
$output[$key] = array(
'cat_id' => array($value['cat_id']),
'prod_id' => $value['prod_id']
);
$temp[$value['prod_id']] = $key;
}
}
First thing that came to my mind is to iterate over your structure, build a helping structure of array_index => prod_id of first occurrence (for this example array(44 => 161, 45 => 164)). You remove every but first and at the same time add prod_id to the first one found.