I'm trying to delete sub array of my multidimensional array, if any of the value is empty, than delete entire sub array. I want a universal function for the same! Dont want to type specific keys. And than ReIndex the newly formed array.
My array is like
Array
(
[0] => Array
(
[name] => Test
[mobile] => 613594551
[email] => test#test.com
)
[1] => Array
(
[name] => Test1
[mobile] => 613594552
[email] => test2#test.com
)
[2] => Array
(
[name] => Test2
[mobile] => 613594553
[email] => test3#test.com
)
[3] => Array
(
[name] => Test3
[mobile] => 613594554
[email] => test4#test.com
)
)
So if my array is
Array
(
[0] => Array
(
[name] =>
[mobile] => 613594551
[email] => test#test.com
)
[1] => Array
(
[name] => Test1
[mobile] =>
[email] => test2#test.com
)
[2] => Array
(
[name] => Test2
[mobile] => 613594553
[email] =>
)
[3] => Array
(
[name] => Test3
[mobile] => 613594554
[email] => test4#test.com
)
)
Than display
Array
(
[0] => Array
(
[name] => Test3
[mobile] => 613594554
[email] => test4#test.com
)
)
Elaborating on Martin's answer, you can use array_filter() for both the source array and the nested array:
$filtered_array = array_filter($array, function($item){
return count($item) == count(array_filter($item));
});
sort($filtered_array); // to reindex
Working example: https://eval.in/521449
Use array_filter() to iterate all records for each person and remove those that have an empty value. Number of records before and after array_filter() has to be equal if all records are filled. If they're not remove the person using unset().
Note, that this function works in-place, so it modifies the original array.
<?php
$array = [
[
'name' => 'Test1',
'mobile' => 123456789,
'email' => null
], [
'name' => 'Test2',
'mobile' => 123456789,
'email' => 'test2#test.com'
], [
'name' => null,
'mobile' => 123456789,
'email' => 'test3#test.com'
],
];
function removeEmpty(&$arr) {
foreach ($arr as $index => $person) {
if (count($person) != count(array_filter($person, function($value) { return !!$value; }))) {
unset($arr[$index]);
}
}
}
removeEmpty($array);
print_r($array);
Prints:
Array
(
[1] => Array
(
[name] => Test2
[mobile] => 123456789
[email] => test2#test.com
)
)
Assuming that an array item might have different keys:
$array = array(
0=>array('name'=>'','test'=>2),
1=>array('name'=>'sadad','test'=>2),
);
foreach($array as $index=>$item) {
$keys = array_keys($item); //here is the assumption
//you can define it before the foreach
//by checking the first array if YOU are 100% sure
//all items in the array have the same keys: name, mobile, email
foreach($keys as $key) {
if(empty($item[$key])) {
unset($array[$index]);
break;
}
}
}
var_dump($array);
Output:
array(1) {
[1]=>
array(2) {
["name"]=>
string(5) "sadad"
["test"]=>
int(2)
}
}
Related
I have a multidimensional array in php and i need to change the column order with the order of a second simple array.
EDIT:
Although both arrays are the same in regard of values and keys, im using this for export with phpexcel, and it generates the xls file with the order of the given array. I need to change that order so the xls file looks that way.
The array looks like this:
Array
(
[0] => Array
(
[name] => Name1
[sn] => Sn1
[somenumber] => 43234234
)
[1] => Array
(
[name] => Name2
[sn] => Sn2
[somenumber] => 4564564
)
[2] => Array
(
[name] => Name3
[sn] => Sn3
[somenumber] => 6575647456745
)
)
And the second array is this:
Array
(
[0] => sn
[1] => name
[2] => somenumber
)
What i need is the first array to be ordered based on the second so it looks like this:
Array
(
[0] => Array
(
[sn] => Name1
[name] => Sn1
[somenumber] => 43234234
)
[1] => Array
(
[sn] => Name2
[name] => Sn2
[somenumber] => 4564564
)
[2] => Array
(
[sn] => Name3
[name] => Sn3
[somenumber] => 6575647456745
)
)
this is how you can sort your array:
$template array:
//template array
$reference = array('sn', 'name', 'somenumber');
$array_to_sort = Array
(
"0" => Array
(
"somenumber" => "Name1",
"sn" => "Sn1",
"name" => "43234234"
),
"1" => Array
(
"sn" => "Name2",
"somenumber" => "4564564",
"name" => "Sn2"
),
"2" => Array
(
"sn" => "Name3",
"name" => "Sn3",
"somenumber" => "6575647456745"
)
);
$ordered_array = [];
foreach ($array_to_sort as $key => $value) {
$ordered_array[] = array_replace(array_flip($reference), $value);
}
print_r($ordered_array);
If all keys always present
// Make template array with correct order of keys
$template = array_flip($second);
foreach($array as &$x) {
// replace values in template
$x = array_replace($template, $x);
}
demo
[original:protected] => Array
(
[user_id] => 65751
[social_id] =>
[parent_id] =>
[org_id] => 1
[type] => 3
[s_id] => 1
[role_id] => 0
[active] => 1
[name] => RX
[first_name] => JJ
[last_name] => DKL
[email] => first#testmail.com
[secondary_email] =>
[username] => cLvcyUr2
)
[1] => User Object
(
[user_id] => 82197
[social_id] =>
[parent_id] =>
[org_id] => 1
[type] => 2
[s_id] => 1
[role_id] => 0
[active] => 1
[name] => sec
[first_name] => XX
[last_name] => J3
[email] => first#testmail.com
[secondary_email] =>
[username] => VfTqXyvJ
)
How to transform the array data mean to keep only two email and username rest should remove
Array (
[0] => Array (
[email] => first#testmail.com
[username] => cLvcyUr2
)
[1] => Array (
[email] => first#testmail.com
[username] => VfTqXyvJ
)
)
How could this possible i do not to unset data one by one it should automatically unset and pick only two value
Did you try something like that :
$index = array_search('user_id', $array);
unset($array[$index]);
Do that for all key you want to remove.
$newArray = [];
foreach ($oldArray as $item) {
$arr = [];
$arr['email'] = $item->email;
$arr['username'] = $item->username;
$newArray[] = $arr;
}
Why not create an empty array and just copy the values you need? Trying to unset everything in your array is a lot of work and is not really maintainable, out of experience.
Note that your pasted code contains both an array and object, but your question is about an array only.
$newArray = [];
foreach ($oldArray as $item) {
$newArray[] = [
'email' => $item->email,
'username' => $item->username
]; // If $item is object
$newArray[] = [
'email' => $item['email'],
'username' => $item['username']
]; // If $item is array
}
var_dump($newArray);
I have an array like below and what I want to achieve is basically remove the keys like #attributes and AddressSop and make them all one level so it removes the parent keys and array but keeps the key value pairs:
[Addresses] => Array
(
[0] => Array
(
[AddrCountry] => US
[AddrLine1] => Test Street
[AddrLine2] => Test
[AddrLine3] => Test
[AddrName] => Mr John Doe
[AddrEmail] => test#test.com
[AddrMasterPriceBook] =>
[AddrMobile] => 123132142242
)
[1] => Array
(
...
)
)
This is how the original array looks. Any help will be awesome thank you.
[Addresses] => Array
(
[0] => Array
(
[#attributes] => Array
(
[AddrCountry] => US
[AddrLine1] => Test Street
[AddrLine2] => Test
[AddrLine3] => Test
[AddrName] => Mr John Doe
)
[AddressSOP] => Array
(
[#attributes] => Array
(
[AddrEmail] => test#test.com
[AddrMasterPriceBook] =>
[AddrMobile] => 123132142242
)
)
)
[1] => Array
(
[#attributes] => Array
(
[AddrCountry] => US
[AddrLine1] => Test Street
[AddrLine2] => Test
[AddrLine3] => Test
[AddrName] => Mr John Doe
)
[AddressSOP] => Array
(
[#attributes] => Array
(
[AddrEmail] => test#test.com
[AddrMasterPriceBook] =>
[AddrMobile] => 123132142242
)
)
)
)
Try this:
foreach ($addresses as $key => $address) {
$addresses[$key] = array_merge($address['#attributes'], $address['AddressSOP']);
}
If you want it to be recursive, you can do something like this:
$filtered = [];
foreach ($addresses as $addressKey => $address) {
array_walk_recursive($address, function($val, $key) use(&$filtered, $addressKey) {
$filtered[$addressKey][$key] = $val;
});
}
print_r($filtered);
This question already has answers here:
Transposing multidimensional arrays in PHP
(12 answers)
Closed 5 months ago.
I need to convert a PHP array that I'm getting from a form submission, so that I can use it more usefully in a db.
Array
(
[first_name] => Array
(
[0] => Ben
[1] => Tom
[2] => Sarah
)
[last_name] => Array
(
[0] => Wills
[1] => Main
[2] => Bliss
)
[email] => Array
(
[0] => ben.wills#argh.com
[1] => tommain#argh.com
[2] => sbliss#argh.com
)
)
to:
Array
(
[0] => Array
(
[first_name] => Ben
[last_name] => Wills
[email] => ben.wills#argh.com
)
[1] => Array
(
[first_name] => Tom
[last_name] => Main
[email] => tommain#argh.com
)
[2] => Array
(
[first_name] => Sarah
[last_name] => Bliss
[email] => sbliss#argh.com
)
)
How can I change the values' key paths so that the first level keys and the second level keys are swapped?
The solution using array_keys, array_values, array_map, call_user_func_array and array_combine functions:
$keys = array_keys($arr); // supposing $arr is your initial array
$data = call_user_func_array("array_map", array_merge([null], array_values($arr)));
$result = array_map(function($v) use($keys){
return array_combine($keys, $v);
}, $data);
print_r($result);
The output:
Array
(
[0] => Array
(
[first_name] => Ben
[last_name] => Wills
[email] => ben.wills#argh.com
)
[1] => Array
(
[first_name] => Tom
[last_name] => Main
[email] => tommain#argh.com
)
[2] => Array
(
[first_name] => Sarah
[last_name] => Bliss
[email] => sbliss#argh.com
)
)
Use the below code. Hope at least this gives some idea how to proceed :)
$array = array(
'first_name' => array('Ben','Tom','Sarah'),
'last_name' => array('Wills','Main','Bliss'),
'email' => array('ben.wills#argh.com','tommain#argh.com','sbliss#argh.com')
);
// loop the array
foreach($array as $key=>$value){
foreach($value as $k=>$v){
// use the first loop key here
$new_array[$k][$key] = $v;
}
}
print_r($new_array);
Out Put:
Array
(
[0] => Array
(
[first_name] => Ben
[last_name] => Wills
[email] => ben.wills#argh.com
)
[1] => Array
(
[first_name] => Tom
[last_name] => Main
[email] => tommain#argh.com
)
[2] => Array
(
[first_name] => Sarah
[last_name] => Bliss
[email] => sbliss#argh.com
)
)
Doing a transform while retaining the key names can be achieved quite easily using PHP's MultipleIterator
$data = array(
'first_name' => array(
0 => 'Ben',
1 => 'Tom',
2 => 'Sarah',
),
'last_name' => array(
0 => 'Wills',
1 => 'Main',
2 => 'Bliss',
),
'email' => array(
0 => 'ben.wills#argh.com',
1 => 'tommain#argh.com',
2 => 'sbliss#argh.com',
),
);
$mi = new MultipleIterator(MultipleIterator::MIT_NEED_ALL | MultipleIterator::MIT_KEYS_ASSOC);
foreach($data as $key => $column) {
$mi->attachIterator(new ArrayIterator($column), $key);
}
$newData = [];
foreach($mi as $row) {
$newData[] = $row;
}
var_dump($newData);
Demo
Is it possible to remove only the associative array who have all values empty?
Data source:
Array
(
[0] => Array
(
[name] => foo
[phone] => 012345
[email] =>
)
[1] => Array
(
[name] => bar
[phone] =>
[email] => yahoo.com
)
[2] => Array
(
[name] =>
[phone] =>
[email] =>
)
)
Desired output:
Array
(
[0] => Array
(
[name] => foo
[phone] => 012345
[email] =>
)
[1] => Array
(
[name] => bar
[phone] =>
[email] => yahoo.com
)
)
I tried this, but unfortunately I will delete all empty values of arrays
$_arr = array_filter(array_map('array_filter', $_arr));
Array
(
[0] => Array
(
[name] => foo
[phone] => 012345
)
[1] => Array
(
[name] => bar
[email] => yahoo.com
)
)
How could I do it? Thank You
Maybe a slicker way, but:
$array = array_filter($array, function($a) { return array_filter($a); });
Since array_filter is using a true or false return to filter; the array_filter in the function is returning either an empty array evaluated as false, or a non-empty array evaluated as true, and the main array_filter is filtering based upon that.
<?php
$collection = array(
"0" => array
(
'name' => "foo",
'phone' => "012345",
'email' => ''
),
"1" => array
(
'name' => "bar",
'phone' => '',
'email' => "yahoo.com",
),
"2" => array
(
'name' => '',
'phone' => '',
'email' => ''
)
);
foreach($collection as $key=> $entry){
if(count(array_filter($entry)) == 0){
unset($collection[$key]);
}
}
print_r($collection);