I have this code to add new elements to a multidimension array:
$this->shopcart[] = array(productID => $productID, items => $items);
So how do i remove an element from this array? I tried this code, but its not working:
public function RemoveItem($item)
{
foreach($this->shopcart as $key)
{
if($key['productID'] == $item)
{
unset($this->shopcart[$key]);
}
}
}
I get this error:
Warning: Illegal offset type in unset in C:\xampplite\htdocs\katrinelund\classes\TillRepository.php on line 50
public function RemoveItem($item)
{
foreach($this->shopcart as $i => $key)
{
if($key['productID'] == $item)
{
unset($this->shopcart[$i]);
break;
}
}
}
That should do the trick.
Update
There is also an alternative way:
if ( false !== $key = array_search($item, $this->shopcart) )
{
unset($this->shopcart[$key];
}
You're not enumerating over indices, but values there, to unset an array index, you have to unset it by index, not by value.
Also, If your array index is actually the productID you can eliminate the loop altogether:
public function RemoveItem($productID)
{
if (isset($this->shopcart[$productID]))
{
unset($this->shopcart[$productID]);
}
}
Your example doesn't show how you are adding items to $this->shopcart, but this may or may not be an option for you depending on the needs of your project. (i.e. not if you need to have seperate instances of the same productid in the cart).
Related
I am looping thru two Arrays. $wooProducts and $data. Both arrays look the same and contain WooCommerce products.
My goal is to loop thru $wooProducts and remove the matched product from $data.
Everything work except the unset() part. Any idea how I can make it work? I tried this as well: unset($data[$matchedProduct]);
// Find function
function find($array, $key) {
foreach ($array as $product) {
if ($product["Name"] == $key) {
return $product;
}
}
}
$updateProducts = [];
// Check if product already exist
foreach ($wooProducts as $wooProduct) {
$matchedProduct = find($data, $wooProduct->post_title);
if ($matchedProduct) {
array_push($updateProducts, $matchedProduct);
unset($data[$wooProduct]); // <---- Not working
}
}
You can use array_search() to find the index and then you can use unset.
array_search($wooProduct->post_title, $data);
I have an array which consists of arrays. So, now suppose I want to retrieve the sku and price whose
key value is 2=>5 and 3=>7 so it should return price=>13 and sku=>bc i.e. that array whose index is at 1 in the array.
Hi I would probably try the following (Same as Riziers comment)
foreach($array as $key => $item) {
if($item[2] == 5 && $item[3] == 7) {
// return price
return $item;
}
}
There is a function array_search, which does what you want but for simple values. You can define your own function that will take not $needle, but callable predicate:
function array_search_callback(callable $predicate, array $array)
{
foreach ($array as $key => $item) {
if ($predicate($item)) {
return $key;
}
}
return false;
}
Having this function your example can be done like this:
$key = array_search_callback(function ($item) {
return $item[2] === '5' && $item[3] === '7';
}, $array);
$result = $key === false ? null : $array[$key];
I could simply return an item from the search function. But to be consistent with the original search function, I am returning the index.
As array_search_callback takes callable as an argument you can provide any criteria you want without the need of modifying the function itself.
Here is working demo.
I am trying to put together a shopping cart system using Laravel.
Here is how things are added:
public function addItem($itemId, $details = []) {
if(isset(Session::get('cart'))) {
Session::push('cart', ['item_id' => $itemId, 'details' => $details]);
} else {
Session::put('cart', ['item_id' => $itemId, 'details' => $details]);
}
}
I know how to drop everything from the cart which is simple by doing:
if(isset(Session::get('cart'))) {
Session::forget('cart');
}
But I don't know how to go about removing a specific item from the cart based on its item_id, currently all I have for this function is:
public function removeItem($itemId) {
if(isset(Session::get('cart'))) {
} else {
}
}
How can I unset and item in the cart based on the key item_id in the sub array?
The Session facade has a forget() function with lets you remove an item from the session. The cool thing about it, is that it internally calls array_forget which allows you to use the "dot" notation. So this is how you do it:
$index = null;
// find out the index of the item to delete
foreach(Session::get('cart') as $i => $item){
if($item['item_id'] == $itemId){
$index = $i;
break;
}
}
// remove by index using the dot notation
if($index != null){
Session::forget('cart.'.$index);
}
Also you could simplify things by using the item_id as actual array key. This should work:
public function addItem($itemId, $details = []) {
Session::set('cart.'.$itemId, ['item_id' => $itemId, 'details' => $details]);
}
public function removeItem($itemId) {
Session::forget('cart.'.$itemId);
}
As far as I know currently there is no way to remove value of array stored in session, but you can try workaraound - load all array from session, remove the array value and set array back to session. Something like this should work:
public function removeItem($itemId) {
if(isset(Session::get('cart'))) {
$cart = Session::get('cart');
unset($cart[$item_id]);
Session::set('cart', $cart);
} else {
}
}
You can use array_forget function for dropping a nested array but you can remove a part using array_except like this:
$array = array_except($array, array('keys', 'to', 'remove'));
SO in your case use:
Session::array_except('cart', ['item_id', $itemId, 'remove']);
for more details please visit this link http://laravel.com/docs/4.2/helpers
I have a question about a recursive PHP function.
I have an array of ID’s and a function, returning an array of „child id’s“ for the given id.
public function getChildId($id) {
…
//do some stuff in db
…
return childids;
}
One childid can have childids, too!
Now, I want to have an recursive function, collecting all the childids.
I have an array with ids like this:
$myIds = array("1111“,"2222“,"3333“,“4444“,…);
and a funktion:
function getAll($myIds) {
}
What I want: I want an array, containing all the id’s (including an unknown level of childids) on the same level of my array. As long as the getChildId($id)-function is returning ID’s…
I started with my function like this:
function getAll($myIds) {
$allIds = $myIds;
foreach($myIds as $mId) {
$childids = getChildId($mId);
foreach($childids as $sId) {
array_push($allIds, $sId);
//here is my problem.
//what do I have to do, to make this function rekursive to
//search for all the childids?
}
}
return $allIds;
}
I tried a lot of things, but nothing worked. Can you help me?
Assuming a flat array as in your example, you simply need to call a function that checks each array element to determine if its an array. If it is, the function calls it itself, if not the array element is appended to a result array. Here's an example:
$foo = array(1,2,3,
array(4,5,
array(6,7,
array(8,9,10)
)
),
11,12
);
$bar = array();
recurse($foo,$bar);
function recurse($a,&$bar){
foreach($a as $e){
if(is_array($e)){
recurse($e,$bar);
}else{
$bar[] = $e;
}
}
}
var_dump($bar);
DEMO
I think this code should do the trick
function getAll($myIds) {
$allIds = Array();
foreach($myIds as $mId) {
array_push($allIds, $mId);
$subids = getSubId($mId);
foreach($subids as $sId) {
$nestedIds = getAll($sId);
$allIds = array_merge($allIds, $nestedIds);
}
}
return $allIds;
}
I have a function that searches a multidimensional array for a key, and returns the path
inside the array to my desired key as a string.
Is there any way I can use this string in php to reach this place in my original array, not to get to the value but to make changes to this specific bracnch of the array?
An example:
$array = array('first_level'=>array(
'second_level'=>array(
'desired_key'=>'value')));
in this example the function will return the string:
'first_level=>second_level=>desired_key'
Is there a way to use this output, or format it differently in order to use it in the following or a similar way?
$res = find_deep_key($array,'needle');
$array[$res]['newkey'] = 'injected value';
Thanks
If the keys path is safe (e.g. not given by the user), you can use eval and do something like:
$k = 'first_level=>second_level=>desired_key';
$k = explode('=>', $k);
$keys = '[\'' . implode('\'][\'', $k) . '\']';
eval('$key = &$array' . $keys . ';');
var_dump($key);
I think you want to do a recursive search in the array for your key? Correct me if i am wrong.
Try this
function recursive_array_search($needle,$haystack) {
foreach($haystack as $key=>$value) {
$current_key=$key;
if($needle===$value OR (is_array($value) && recursive_array_search($needle,$value) !== false)) {
return $current_key;
}
}
return false;
}
Taken from here http://in3.php.net/manual/en/function.array-search.php#91365
You need something like:
find_key_in_array($key, $array, function($foundValue){
// do stuff here with found value, e.g.
return $foundValue * 2;
});
and the implementation would be something like:
function find_key_in_array($key, $array, $callback){
// iterate over array fields recursively till you find desired field, then:
...
$array[$key] = $callback($array[$key]);
}
If you need to append some new sub-array into multidimensional complex array and you know where exactly it should be appended (you have path as a string), this might work (another approach without eval()):
function append_to_subarray_by_path($newkey, $newvalue, $path, $pathDelimiter, &$array) {
$destinationArray = &$array;
foreach (explode($pathDelimiter, $path) as $key) {
if (isset($destinationArray[$key])) {
$destinationArray = &$destinationArray[$key];
} else {
$destinationArray[$newkey] = $newvalue;
}
}
}
$res = find_deep_key($array,'needle');
append_to_subarray_by_path('newkey', 'injected value', $res, '=>', $array);
Of course, it will work only if all keys in path already exist. Otherwise it will append new sub-array into wrong place.
just write a function that takes the string and the array. The function will take the key for each array level and then returns the found object.
such as:
void object FindArray(Array[] array,String key)
{
if(key.Length == 0) return array;
var currentKey = key.Split('=>')[0];
return FindArray(array[currentKey], key.Remove(currentKey));
}