Remove unwanted elements from subarrays in multidimensional array - php

I have a multidimensional array like this:
[
[
'id' => 1,
'name' => 'John',
'address' => 'Some address 1'
'city' => 'NY'
],
[
'id' => 2,
'name' => 'Jack',
'address' => 'Some address 2'
'city' => 'NY'
]
...
[ ... ]
]
How can I remove elements in all subarrays and only retain the id and name keys with their values?

Would this work?
$result = array_map(function($arr) {
return [
'id' => $arr['id'],
'name' => $arr['name']
];
}, $orig_array);

You want to retain the first two associative elements, so you can make array_slice() calls within array_map(). (Demo)
var_export(
array_map(fn($row) => array_slice($row, 0, 2), $array)
);
Or mapped called of array_intersect_key() against an establish whitelist array. (Demo)
$keep = ['id' => '', 'name' => ''];
var_export(
array_map(
fn($row) => array_intersect_key($row, $keep),
$array
)
)
Or, you could use array destructuring inside of a classic foreach() and make iterated compact() calls. (Demo)
$result = [];
foreach ($array as ['id' => $id, 'name' => $name]) {
$result[] = compact(['id', 'name']);
}
var_export($result);

If you want to edit the same array in place, you can simply iterate over them and unset them.
<?php
$preserve_keys = ['id','name'];
foreach($arr as &$data){
foreach($data as $key => $value){
if(!in_array($key,$preserve_keys)){
unset($data[$key]);
}
}
}
If you want it as a separate result, loop over and add it to the new array.
<?php
$new_result = [];
foreach($arr as $data){
$new_result[] = [
'id' => $data['id'],
'name' => $data['name']
];
}
print_r($new_result);

Related

php multidimensional array count dynamically

I have two arrays $users and $find. I need count how many matches in $users if $find array would be changed.
$users = array(
[
'name' => 'Jim',
'sname' => 'Carrey'
],
[
'name' => 'Michael',
'sname' => 'Douglas'
],
[
'name' => 'Michael',
'sname' => 'Jackson'
],
[
'name' => 'Michael',
'sname' => 'Jordan'
]
);
Find array changed dynamically. It may be:
$find = array (
'name' => array('Michael'),
'sname' => array('Douglas', 'Jordan')
);
OR:
$find = array (
'sname' => array('Carrey', 'Jordan')
);
I'm looking for a one-size-fits-all solution for for any values in $find array.
Thanks!
I can count if I have static keys and values in $find array:
$result = array_filter($users, function($user) {
return in_array($user['name'], ['Michael', 'Jim']) && in_array($user['sname'], ['Douglas', 'Jordan', 'Carrey']);
});
$count = count($result);
print_r($result);
But I don't understand how count if it should be dynamic keys and values in $find array.
If you want to deal with an unknown number of items in $find, then you will need to loop over them. The use keyword helps to "inject" $find into your callback function. In your loop, you can return false, if the in_array check for the current find item results in false, otherwise you return true after the loop.
$result = array_filter($users, function($user) use ($find) {
foreach($find as $col => $values) {
if(!in_array($user[$col], $values)) {
return false;
}
}
return true;
});
$result=array_intersect($users,$find);
print_r($result);

PHP grouping content of multidimensional array with new structure

I usually use Eloquent so transposing the data is much easier. However i'm struggling to this in vanilla PHP.
I have tried array_map(null, ...$array) however get an error due to it not being an array.
I have got the following keyed array:
[
'email' => [
"william.pool#gmail.com",
"martynleeball#gmail.com"
],
'lastName' => [
'Pool',
'Ball'
],
'firstName' => [
'William',
'Martyn'
],
'id' => [
'j8zwyk',
'1'
]
]
I need to convert this to the following format:
[
0 => [
'email' => "william.pool#gmail.com",
'lastName' => 'Pool',
'firstName' => 'William',
'id' => 'j8zwyk'
],
1 => [
'email' => "martynleeball#gmail.com",
'lastName' => 'Ball',
'firstName' => 'Martyn',
'id' => '1'
]
]
Create new array with length 2 and loop through origin array. In loop insert relevant item into new array.
So if your array has only 2 item per key use
$newArr = [];
foreach($arr as $key=>$item){
$newArr[0][$key] = $item[0];
$newArr[1][$key] = $item[1];
}
But if it has unknown item use
$newArr = [];
foreach($arr as $key=>$item){
foreach($item as $key2=>$item2)
$newArr[$key2][$key] = $item2;
}
Check result in demo
$newArray = [];
foreach ($array as $key => $value) {
for ($i = 0; $i < count($value); $i++) {
$newArray[$i][$key] = $value[$i];
}
}

Convert an array with index and value into an array

I have an array as key => value pair such as:
$array = [ 10 => 'Windows', 12 => 'Keyboard', 15 => 'Monitor' ];
What I would like to achieve without using any foreach or loops the following:
$converted = [
0 => [ 'id' => 10, 'name' => 'Windows'],
1 => [ 'id' => 12, 'name' => 'Keyboard'],
2 => [ 'id' => 15, 'name' => 'Monitor']
];
Here they indices in new array doesn't matter. Any tips??
No foreach and no loop, but now there is a closure:
$result = array_map(function ($id, $name) {
return [
'id' => $id,
'name' => $name
];
}, array_keys($array), array_values($array));
Even if there was a PHP function that did this exactly, it would be using a loop internally.
function do_what_ghazanfar_mir_wants(array $array) {
return array_map(function ($id, $name) {
return [
'id' => $id,
'name' => $name
];
}, array_keys($array), array_values($array));
}
And the single liner is:
$result = do_what_ghazanfar_mir_wants($array);
And the foreach approach for comparison:
$res = [];
foreach ($array as $id => $name) {
$res[] = [ 'id' => $id, 'name' => $name ];
}
If you want to keep it really short then array_walk will do it in one line:
array_walk($array, function(&$value, $key) { $value = ['id' => $key, 'name' => $value]; });
See https://3v4l.org/OEohi
But I think a foreach loop is probably going to be a lot more readable.
Do it with array_map(), Just pass the keys array_keys($array) and values $array as the parameter of your array_map()
<?php
$array = [ 10 => 'Windows', 12 => 'Keyboard', 15 => 'Monitor' ];
function map_by_key($m, $n)
{
return(array('id' => $m, 'name'=>$n));
}
$output = array_map("map_by_key", array_keys($array),$array);
print '<pre>';
print_r($output);
print '</pre>';
?>
DEMO: https://3v4l.org/iTVSm

PHP array key exists from string

I have an array:
<?php
$array = [
'fruits' => [
'apple' => 'value',
'orange' => 'value'
],
'vegetables' => [
'onion' => 'value',
'carrot' => 'value'
];
I also have a string:
$string = 'fruits[orange]';
Is there any way to check if the - array key specified in the string - exists in the array?
For example:
<?php
if(array_key_exists($string, $array))
{
echo 'Orange exists';
}
Try this one. Here we are using foreach and isset function.
Note: This solution will also work for more deeper levels Ex: fruits[orange][x][y]
Try this code snippet here
<?php
ini_set('display_errors', 1);
$array = [
'fruits' => [
'apple' => 'value',
'orange' => 'value'
],
'vegetables' => [
'onion' => 'value',
'carrot' => 'value'
]
];
$string = 'fruits[orange]';
$keys=preg_split("/\[|\]/", $string, -1, PREG_SPLIT_NO_EMPTY);
echo nestedIsset($array,$keys);
function nestedIsset($array,$keys)
{
foreach($keys as $key)
{
if(array_key_exists($key,$array))://checking for a key
$array=$array[$key];
else:
return false;//returning false if any of the key is not set
endif;
}
return true;//returning true as all are set.
}
It would be a lot easier to check the other way around. As in check if the key is in the string. Since keys are unique, there's no way you have duplicates.
$array = [
'fruits' => [
'apple' => 'value',
'orange' => 'value'
],
'vegetables' => [
'onion' => 'value',
'carrot' => 'value'
]
];
$string = 'fruits[orange]';
$keys = array_keys($array['fruits']);
foreach($keys as $fruit) {
if(false !== stripos($string, $fruit)) {
return true;
}
}
While this solution is not necessarily ideal, the problem to begin with isn't exactly common.
You can walk recursively:
$array = [
'fruits' => [
'apple' => 'value',
'orange' => 'value'
],
'vegetables' => [
'onion' => 'value',
'carrot' => 'value'
]
];
$exists = false;
$search = "orange";
array_walk_recursive($array, function ($val, $key) use (&$exists,$search) {
if ($search === $key) { $exists = true; }
});
echo ($exists?"Exists":"Doesn't exist");
Prints:
Exists
Example: http://sandbox.onlinephpfunctions.com/code/a3ffe7df25037476979f4b988c2f36f35742c217
Instead of using regex or strpos like the other answers, you could also simply split your $string on [ and resolve the keys one by one until there's only one key left. Then use that last key in combination with array_key_exists() to check for your item.
This should work for any amount of dimensions (eg fruit[apple][value][1]).
Example:
<?php
$arr = [
'fruits' => [
'orange' => 'value'
]
];
// Resolve keys by splitting on '[' and removing ']' from the results
$keys = 'fruits[orange]';
$keys = explode("[", $keys);
$keys = array_map(function($s) {
return str_replace("]", "", $s);
}, $keys);
// Resolve item.
// Stop before the last key.
$item = $arr;
for($i = 0; $i < count($keys) - 1; $i++) {
$item = $item[$keys[$i]];
}
// Check if the last remaining key exists.
if(array_key_exists($keys[count($keys)-1], $item)) {
// do things
}
You can explode and check the indices of the array.
$array = array(
'fruits' => [
'apple' => 'value',
'orange' => 'value'
],
'vegetables' => [
'onion' => 'value',
'carrot' => 'value'
]);
$string = 'fruits[orange]';
$indexes = (preg_split( "/(\[|\])/", $string));
$first_index= $indexes[0];
$seconnd_index= $indexes[1];
if(isset($array[$first_index][$seconnd_index]))
{
echo "exist";
}
else
{
echo "not exist";
}
DEMO

push certain elements into array php

I want to know that is there a way to insert certain elements of an array into a new array. I mean I have an array containing 10 objects. Each object has 3 or four fields for example id, name , age , username. now I want to insert the id's of all the objects into the new array with a single call.Is there anyway to do that.
$array = [
[0] => [
id =>
name =>
],
[1] = > [
id =>
name =>
]
]
and so on now I want to insert all the id's of all the object into a new array with a single call. Is there a way to do that?
Use array_map() function.
Here is your solution:-
$ids = array_map( function( $arr ){
return $arr["id"];
}, $arr );
echo '<pre>'; print_r($ids);
A basic foreach loop will do the job just fine
$firstArray = array(
array(
'id' => 1,
'name' => 'abc'
),
array(
'id' => 2,
'name' => 'def'
),
array(
'id' => 3,
'name' => 'gh'
)
);
$onlyIds = array();
$onlyKeys = array();
//To get the array value 'id'
foreach($firstArray as $value){
$onlyIds[] = $value['id'];
}
//To get the array keys
foreach($firstArray as $key => $value){
$onlyKeys[] = $key;
}
You could use array_walk which could be considered a "single call"
$array = array(0 => array('id', 'name', 'age'), 1 => array('id', 'name', 'age'));
array_walk($array, function($item, $key) {
// $key is 0 or 1
// $item is either id, name, age
});
You can use array_column.
$arr = [ ['id' => 1, 'username' => 'a'], ['id' => 2, 'username' => 'b'] ];
$ids = array_column($arr, 'id')
$ids == [1, 2]

Categories