I have a collection of array it contains both numeric index as well as non numeric. I want to unset all the numeric indexes.
My array is something like this .
Array
(
[554] => Array
(
[0] => 554
[1] => Jiaqi Zheng
[2] => Female
[3] => 28
[4] => Table Tennis
[5] =>
[6] =>
[7] =>
[8] =>
[rank] => 554
[athlet_name] => Jiaqi Zheng
[gender] => Female
[sport] => Table Tennis
)
[555] => Array
(
[0] => 555
[1] => Zach Ziemek
[2] => Male
[3] => 23
[4] => Athletics
[5] =>
[6] =>
[7] =>
[8] =>
[rank] => 555
[athlet_name] => Zach Ziemek
[gender] => Male
[sport] => Athletics
)
)
Here i have to unset all the numeric index .
I used unset like this and its working fine for me .
unset(
$history_years_wise_country_wise_details_arr[ $history_years_wise_country_wise_details_info[0]][0],
$history_years_wise_country_wise_details_arr[$history_years_wise_country_wise_details_info[0]][1],
$history_years_wise_country_wise_details_arr[$history_years_wise_country_wise_details_info[0]][2],
$history_years_wise_country_wise_details_arr[$history_years_wise_country_wise_details_info[0]][3],
$history_years_wise_country_wise_details_arr[$history_years_wise_country_wise_details_info[0]][4],
$history_years_wise_country_wise_details_arr[$history_years_wise_country_wise_details_info[0]][5],
$history_years_wise_country_wise_details_arr[$history_years_wise_country_wise_details_info[0]][6],
$history_years_wise_country_wise_details_arr[$history_years_wise_country_wise_details_info[0]][7],
$history_years_wise_country_wise_details_arr[$history_years_wise_country_wise_details_info[0]][8]
);
Is there any way I will reduce the lines of codes? here 0 to 8 are in one series.
Can I unset all index in one line of code , as all are numeric?
Is it possible to use regular expression instead?
I want something like
unset(
$history_years_wise_country_wise_details_arr[ $history_years_wise_country_wise_details_info[0]][anything_which_will_take_index_from_0_to_8]);
Any suggestions?
Thank you
You could use array_filter() with is_string() function as its callback function:
$array = array_filter($array, 'is_string', ARRAY_FILTER_USE_KEY);
Use looping.
foreach ($array as $key => $value) {
if (is_numeric ($key)) {
unset($array [$key]);
}
}
Or use array_filter
$filtered = array_filter(
$array,
function ($key) {
return !is_numeric($key);
},
ARRAY_FILTER_USE_KEY
);
You shoud used foreach loop with is_numeric function like
foreach ($your_array as $key => $value) {
if (!is_numeric($key)) {
unset($arr[$key]);
}
}
i think there is no need of any regular expression
Since you have array inside array first you need to use array_map() and then traverse through array using array_filter(),
considering $array as your array:
$resultData = array_map([$this, 'allData'], $array);
public function allData($data)
{
$numericKeys = array_filter(array_keys($data), function ($k) {
return is_int($k);
});
// Updated Code
$arrayKeys = array_diff(array_keys($data),$numericKeys);
return array_intersect_key($data,array_flip($arrayKeys));
}
Related
I have the following structure of an array which is decoded from a JSON object. From this array result I need to fork widgets for processing. It is an unstable JSON array so the parent keys may differs in future but the widgets will not.
(
[2] => Array
(
[MA] => Array
(
[0] => Array
(
[activities] => Array
(
[0] => Array
(
[activity_id] => 3
[activity_name] => Excavation
[activity_unique_id] => EXCAV-d435
[created_date] => 2021-02-08 21:42:53
[end_date] => 2021-02-08 21:42:08
[fk_client_id] => 1
[fk_main_activity] => 3
[fk_project_id] => 2
[relation_type] => MA-A-SA-W
[start_date] => 2021-02-08 21:42:08
[widgets] => Array
(
[0] => Array
(
[activity_mapping] => STRUC-be4c
[check_box_val] => 0
[checkbox_unique_id] => EXCAV-dceae
[checkbox_widget_id] => 5
[created_date] => 2021-02-08 21:43:12
)
)
)
)
[created_date] => 2021-02-08 21:42:44
[end_date] => 2021-02-08 21:42:08
[fk_client_id] => 1
[fk_floor_ids] => 7
[fk_project_id] => 2
[main_activity_id] => 3
[main_activity_name] => Structure MA1
[main_activity_unique_id] => STRUC-be4c
[relation_type] => MA-A-SA-W
[sequence_no] => 1
[start_date] => 2021-02-08 21:42:08
[tower_ids] => 4
[widgets_ids] =>
)
...
it is a big source So I cut shorted it. From the above result set I only need to fork the following widgets object.
[widgets] => Array
(
[0] => Array
(
[activity_mapping] => STRUC-be4c
[check_box_val] => 0
[checkbox_unique_id] => EXCAV-dceae
[checkbox_widget_id] => 5
[created_date] => 2021-02-08 21:43:12
)
)
)
Thanks in advance.
This recursive function searches for the first occurrence of a key in a multidimensional array and returns its value.
function array_find_key(array $array, $key) {
if (array_key_exists($key, $array)) {
return [$key => $array[$key]];
} else {
foreach($array as $item) {
if (is_array($item) && $result = array_find_key($item, $key)) {
return $result;
}
}
}
}
$result = array_find_key($array, 'widgets');
fiddle
The answer from #id'7238 is designed to search for a qualifying value in the current level before attempting to traverse a deeper level. The nuance in my answer (which does not call array_key_exists()) is that it checks keys as it traverses a level and will go down a level as soon as a non-qualifying subarray is encountered.
While looping, if the key is found, the payload is returned (and potentially passed up the recursive stack). If a value is array type data, then the next level down is processed -- if that level contains a qualifying key, it is passed up the stack.
If there are no qualifying keys in the input array, then null will be returned.
Code: (Demo)
function searchByKey(array $array, $find) {
foreach($array as $k => $v) {
if ($k === $find) {
return [$k => $v];
}
if (is_array($v)) {
$result = searchByKey($v, $find);
if ($result) {
return $result;
}
}
}
}
var_export(searchByKey($a, 'foo'));
For fun, if the nesting level will be the same just with the keys being different, this will give you the widgets array:
$result = current(current(current(current(current($array)))))['widgets'];
This will give you the array under the widgets array:
$result = current(current(current(current(current(current($array)))))['widgets']);
The first example will only work if the widgets array is 5 levels deep in the array and for the second if there is only 1 array under widgets (if there are more you will get the first).
I have this arrays:
$main = array("Name","Age");
$fname =array("Peter","Ben","Joe");
$age = array("35","37","43");
I need to combine it. Output array must be:
[0] =>
[Name] => [Peter]
[Age] => [35]
[1] =>
[Name] => [Ben]
[Age] => [37]
[2] =>
[Name] => [Joe]
[Age] => [43]
And so on. I have tried array_combine, but it gives an error, cuz $main contains only two values, array_merge combine arrays not exactly i want, it adds any next array to the end of result array.
How to solve my issue? Help , please!
Something like this should do:
$result = array_map(
function () use ($main) {
return array_combine($main, func_get_args());
},
$fname,
$age
);
PHP 5.6+ allows this nicer syntax for the callback:
function (...$vals) use ($main) {
return array_combine($main, $vals);
}
Though I would first point out that this is a rather peculiar dataset to end up with, and you should maybe see if there's something you can do before this to get your data in better shape so you don't need to bend over backwards like this in the first place.
The solution using array_map and array_combine functions:
$result = array_map(function($v) use($main){
return array_combine($main, $v);
}, array_map(null, $fname, $age));
print_r($result);
The same can be achieved with regular foreach loop + array_combine function:
$result = [];
foreach ($fname as $k => $v) {
$result[] = array_combine($main, [$v, $age[$k]]);
}
The output:
Array
(
[0] => Array
(
[Name] => Peter
[Age] => 35
)
[1] => Array
(
[Name] => Ben
[Age] => 37
)
[2] => Array
(
[Name] => Joe
[Age] => 43
)
)
this is what you want :
$newArray = [];
$main = array("Name","Age");
$fname =array("Peter","Ben","Joe");
$age = array("35","37","43");
$newArray = array_combine($fname, $age);
$array = [];
foreach($newArray as $key => $value) {
$array[] = [
$main[0] => $key,
$main[1] => $value
];
}
var_dump($array);
I am new to php and my problem is i have 2 arrays the first one is from another page via post and read into an array via post_get
Array (
[0] => 93
[1] => 25
[2] => 5
[3] => 4
[4] => 36
)
and my second array looks like this
Array (
[25] => Estonia
[20] => France
[4] => Germany
[5] => Greece
[75] => Hungary
[93] => India
[36] => Italy
)
what i want to do is if the array looks like the first one then it uses the numbers from the array and with the help from the second array makes a new array that only contains
Array (
[0] => India
[1] => Estonia
[2] => Greece
[3] => Germany
[4] => Italy
)
and using this doesn't work
$group is the first array
$array is the one with the country names
foreach ($group as $value) {
if (in_array($value, $array)) {
}
else {
echo "The group ".$value." does not exist";
}
}
You can do this many ways. Here is a simple one:
$new = [];
foreach ($group as $groupId) {
if (isset($array[$groupId])) {
$new[] = $array[$groupId];
}
}
I would do it like this. Flip $group and find the key intersection with $array:
$result = array_intersect_key($array, array_flip($group));
That will retain the keys, so if you want to re-index:
$result = array_values(array_intersect_key($array2, array_flip($array1)));
No need to use in_array just add some if checking and two foreach loops and use the key of the first array to the index of the second one.
Idea:
$array3 = array();
foreach($array1 as $key) {
if(isset($array2[$key])) { // add some checking just so make sure no undefined indices
$array3[] = $array2[$key];
}
}
Another alternative solution using array_map function:
$result = array_map(function($v) use($array){
return isset($array[$v])? $array[$v] : $v;
}, $group);
I have called core php function from controller of Yii2 in that in_array() function is not working but I have called individually then it is working.
following is my array which I have passed searchForId().
Array
(
[1] => Array
(
[2] => PRICE:
)
[4] => Array
(
[1] => S/NO
[3] => INSULATED TANK SIZE
[7] => QTY
[8] => U.PRICE(Qr.)
[10] => TOTAL PRICE (Qr.)
)
[5] => Array
(
[1] => 01
[3] => FZ 198(S) (11 x 6 x 3MH)
w/p (3+3)
[7] => 1 SET
[8] => 390,197.00
[10] => 390,197.00
)
[6] => Array
(
[1] => 02
[3] => FZ 36(S) (2 x 6 x 3MH)
w/p (3+3)
[7] => 1 SET
[8] => 121,232.00
[10] => 121,232.00
)
[7] => Array
(
[8] => Total in QAR
[10] => 511,429.00
)
)
this type of array I have got from excel sheet which I have read.
and my function is:
public function searchForId($array) {
foreach ($array as $key => $val) {
if (in_array('S/NO', $val)) {
return $key;
}
}
return null;
}
where I am doing wrong please help me.Thank You in advance!!
It seems to me you just need to do:
<?php
$array = [
"S/NO",
"INSULATED TANK SIZE",
"QTY",
"U.PRICE(Qr.)",
"TOTAL PRICE (Qr.)"
];
public function searchForId($array) {
$key = array_search('S/NO', $array);
return $key;
}
var_dump(searchForId($array));
Results here.
array_search() returns you the key already, or false if value is not found. Using in_array you won't directly get the key, if that's your aim. You could check if the return value is false|null at the place you call this function. I would do return $key ?? null(php 7+)
UPDATE
Here's how you can do with the last array you have given. Also see here.
public function searchForId($array) {
foreach($array as $k => $sub){
$key = array_search('S/NO', $sub);
if($key !== false){
return $key;
} else {
continue;
}
}
return null;
}
var_dump(searchForId($array));
Since the $key is int(0), and in all other cases you get bool(false) from array_search, you should check whether the $key is literally false and if so, continue to the next array :-)
Change your if statement as
if (in_array('S/NO', $val)) {
Well, the most reliable would to use array_search which would eliminate your whole function -
$key = array_search('S/NO', $array); //will return 1 for S/No and 7 for QTY.
Write array search inside your searchForId() function or try by trimming the values of array like shown above.
I've "inherited" some data, which I'm trying to clean up. The array is from a database which, apparently, had no keys.
The array itself, is pretty long, so I'm simplifying things for this post...
[0] => Array
(
[id] => 2
[uid] => 130
[eid] => 8
[ename] => Standard
[eaction] => Check
)
[1] => Array
(
[id] => 2
[uid] => 110
[eid] => 8
[ename] => Standard
[eaction] => Check
)
[2] => Array
(
[id] => 2
[uid] => 200
[eid] => 8
[ename] => Standard
[eaction] => Check
)
I'm trying to shift things around so the array is multidimensional and is grouped by ename:
[0] => Array
(
[Standard] => Array
(
[id] => 2
[uid] => 130
[eid] => 8
[eaction] => Check
)
)
[0] => Array
(
[Standard] => Array
(
[id] => 2
[uid] => 130
[eid] => 8
[eaction] => Check
)
)
[0] => Array
(
[Standard] => Array
(
[id] => 2
[uid] => 130
[eid] => 8
[eaction] => Check
)
)
Anyone know how to do something like this?
You can use usort() to sort an array by a user-defined function. That function could compare the ename fields. Then it's just a simple transformation. Like:
usort($array, 'cmp_ename');
function cmp_ename($a, $b) {
return strcmp($a['ename'], $b['ename']);
}
and then:
$output = array();
foreach ($array as $v) {
$ename = $v['ename'];
unset($v['ename']);
$output[] = array($ename => $v);
}
$outputarray = array();
foreach($inputarray as $value) {
$outputarray[] = array($value['ename'] => $value);
}
would accomplish what your examples seem to indicate (aside from the fact that your 'result' example has multiple things all with key 0... which isn't valid. I'm assuming you meant to number them 0,1,2 et cetera). However, I have to wonder what benefit you're getting from this, since all it appears to be doing is adding another dimension that serves no purpose. Perhaps you could clarify your example if there are other things to take into account?
$outputarray = array();
foreach($inputarray as &$value) {
$outputarray[][$value['ename']] = $value;
unset($value['ename']);
} unset($value);
I'm guessing that this is what you're asking for:
function array_group_by($input, $field) {
$out = array();
foreach ($input as $row) {
if (!isset($out[$row[$field]])) {
$out[$row[$field]] = array();
}
$out[$row[$field]][] = $row;
}
return $out;
}
And usage:
var_dump(array_group_by($input, 'ename'));
philfreo was right but he was also off a little. with his code every time you encounter an array element with an ['ename'] the same as one you've already gone through it will overwrite the data from the previous element with the same ['ename']
you might want to do something like this:
$output = array();
foreach ($YOURARRAY as $value) {
$output[$value['ename']][] = $value;
}
var_dump($output); // to check out what you get