Unset multiple intems in array - php

Is there a PHP built-in function to unset multiple array items by key?
That would be a native equivalent of:
foreach($badElements as $k) {
unset($allElements[$k]);
}
or, even better:
$keys = array_keys($badElements);
foreach($keys as $k) {
unset($allElements[$k]);
}

The following doesn't fullfill your requirement in complete since it's not in-situ. But maybe you're ok with copying the array:
$v = array("lol"=>"blub", "lal"=>"blab", "lulz"=>"gagh");
$k = array("lol", "lulz");
var_dump(array_diff_key($v, array_flip($k)));
[ run it on codepad ]

You could create an array of the keys you want to remove and loop through, explicitly unsetting them.
Examples:
$removeKeys = array('name', 'email');
foreach($removeKeys as $key) {
unset($badElements[$key]);
}
Or you could point the variable to a new array that has the keys removed.
$badElements = array_diff_key($badElements, array_flip($removeKeys));
or pass all of the array members to unset().
unset($badElements['name'], $badElements['email'])

Related

clone array and add a subarray

i have the following problem. i have a large array structure which i assign values from a sql statement:
$data[$user][$month]['id'] = $data->id;
$data[$user][$month]['company'] = $data->company;
...
...
and around 30 other values.
i need to clone this array ($data) and add a subarray like:
$data[$user][$month][$newsubarray]['id'] = $data->id;
$data[$user][$month][$newsubarray]['company'] = $data->company;
...
...
i need to clone it because the original array is used by many templates to display data.
is there a way to clone the array and add the subarray without assign all the values to the cloned array? this blows up my code and is very newbi, but works.
You can use array_map, check the live demo
if you want to pass parameter to array_map(), use this
array_map(function($v) use($para1, $para2, ...){...}, $array);
Here is the code,
<?php
$array =array('user'=> array('month'=>array('id' =>2, 'company' => 3)));
print_r($array);
print_r(array_map(function($v){
$arr = $v['month'];
$v['month'] = [];
$v['month']['newsubarray'] = $arr;
return $v;}
, $array));
You can iterate through the array with nested foreach loops.
It would look similar to this:
foreach ($data as $user=>$arr2) {
foreach ($arr2 as $month=>$arr3) {
foreach ($arr3 as $key=>$value) {
$data[$user][$month][$newsubarray][$key] = $value;
}
}
}
Your last level of array, you can create object, for holding data with implementing ArrayAccess. Then simply by reference, assign object in desire places. This way, you can hold 1 object and use it multi places, but if you change in one - this change in all.
Then you addictionaly, can implements __clone method to clone object correctly.

Change array keys to lowercase

I'm looking for a nifty php solution to replace a standard forloop. i dont care at all about the inner workings of my normalize method.
Here is my code:
$pairs=[];
foreach($items as $key => $val){
$key = $this->normalizeKey($key);
$pairs[$key] = $val;
}
private function normalizeKey($key)
{
// lowercase string
$key = strtolower($key);
// return normalized key
return $key;
}
I'd like to learn the PHP language a bit better. I thought array_walk would be nice to use, but that operates on the values and not the keys.
I am looking for a PHP array method that can perform this code instead of a foreach loop.
You want array_change_key_case
$pairs = array_change_key_case($items);
Just for fun, though it requires three functions. You can replace strtolower() with whatever since this can already be done with array_change_key_case():
$pairs = array_combine(array_map('strtolower', array_keys($items)), $items);
Get the keys from $items
Map the array of keys to strtolower()
Combine the new keys with $items values
You can also use an anonymous function as the callback if you need something more complex. This will append -something to each key:
$pairs = array_combine(array_map(function ($v) {
return $v . '-something';
},
array_keys($items)), $items);
You can normalise the keys and store them and their corresponding values in a temporary array and assign it to your original $pairs array.
Like so:
$normalised = [];
foreach($pairs as $key => $value) {
$normalised[$this->normalizeKey($key)] = $value;
};
$pairs = $normalised;
Edit 2022: Or better yet, use #Sherif's answer as it uses a standand library function

Change a value in an array in a loop

I have an array, I need to loop through and change it's value:
foreach ($input['qualification'] as &$_v) {
$_v = ucwords($_v);
}
But this only works for the first item in the array. When I remove the ampersand it loops through the entire array, but obviously the changes are not made.
If you're trying to apply a function to all of the values in an array I would recommend using array_map() instead.
Applies the callback to the elements of the given arrays
$qualifications = array_map('ucwords', $input['qualification']);
Demo
$input['qualification'] = array('high school', 'inter school', 'bachelor of scinece', 'master of science');
foreach ($input['qualification'] as &$_v) {
$_v = ucwords($_v);
}
echo "<pre>";print_r($input['qualification']);
Here is how to do it more slowly, with explicit reference to the index, in case your actual programming task requires the value of the index.
https://eval.in/436395
$input = array('juggling','french','math');
foreach ($input as $i=>$v) {
$input[$i] = ucwords($v);
}

PHP push values into associative array

I can't find an answer to this anywhere.
foreach ($multiarr as $array) {
foreach ($array as $key=>$val) {
$newarray[$key] = $val;
}
}
say $key has duplicate names, so when I am trying to push into $newarray it actually looks like this:
$newarray['Fruit'] = 'Apples';
$newarray['Fruit'] = 'Bananas';
$newarray['Fruit'] = 'Oranges';
The problem is, the above example just replaces the old value, instead of pushing into it.
Is it possible to push values like this?
Yes, notice the new pair of square brackets:
foreach ($multiarr as $array) {
foreach ($array as $key=>$val) {
$newarray[$key][] = $val;
}
}
You may also use array_push(), introducing a bit of overhead, but I'd stick with the shorthand most of the time.
I'll offer an alternative to moonwave99's answer and explain how it is subtly different.
The following technique unpacks the indexed array of associative arrays and serves each subarray as a separate parameter to array_merge_recursive() which performs the merging "magic".
Code: (Demo)
$multiarr = [
['Fruit' => 'Apples'],
['Fruit' => 'Bananas'],
['Fruit' => 'Oranges'],
['Veg' => 'Carrot'],
//['Veg' => 'Leek'],
];
var_export(
array_merge_recursive(...$multiarr)
);
As you recursively merge, if there is only one value for a respective key, then a subarray is not used, if there are multiple values for a key, then a subarray is used.
See this action by uncommenting the Leek element.
p.s. If you know that you are only targetting a single column of data and you know the key that you are targetting, then array_column() would be a wise choice.
Code: (Demo)
var_export(
['Fruit' => array_column($multiarr, 'Fruit')]
);

PHP Array Combination Best Method

given the following arrays in php, how can i best merge them together
$masterkeys = array('Key1','Key2');
$settings_foo = array(
array('ID'=>'Key1',
'Foo_Setting'=>'SomeValue'));
$settings_bar = array(
array('ID'=>'Key1',
'Bar_Setting'=>'SomeOtherValue'));
in the end I need $masterkeys to be the combination of each of the settings_[foo|bar] arrays.
Array( ['Key1'] = Array('Foo_Setting'=>'SomeValue','Bar_Setting'=>'SomeOtherValue') );
I do know I can use a couple foreach loops on this, but just wondering if there are a couple PHP array functions that can splice them together.
While you can use some of PHP's array functions, your input data isn't in a very nice format. You'll have the fewest iterations (and probably best performance) by writing them yourself:
# create an array of $masterkey => array()
$result = array_combine($masterkeys, array_fill(0, count($masterkeys), array()));
# loop through each settings array
foreach (array($settings_foo, $settings_bar) as $settings)
{
foreach ($settings as $s)
{
# merge the array only if the ID is in the master list
$key = $s['ID'];
if (array_key_exists($key, $result))
$result[$key] = array_merge($result[$key], $s);
}
}
# unset all extraneous 'ID' properties
foreach (array_keys($result) as $i)
unset($result[$i]['ID']);
var_dump($result);
As an alternative, you could look into array_map and array_filter, but due to the way the data is structured, I'm not sure they'll be of much use.
I'm not sure how your $masterkeys array plays in here, but array_merge_recursive may do what you want.

Categories