php array match within a two dimensional array - php

for example, I have a array:
$objects = ['car', 'cat', 'dog', 'Peter'];
and another:
$types = [
'man' => ['Peter', 'John','...'],
'animal' => ['pig', 'cat', 'dog', '...'],
'vehicle' => ['bus', 'car', '...']
];
and my goal is get an array like:
$result = [
'man' => ['Peter'],
'animal' => ['cat', 'dog'],
'vehicle' => ['car']
]
what is the most efficient way to search within an array, in my current work, I use two foreach loop to search but figured it's too slow, I have about thousands of elements in my array.

Use array_intersect:
foreach ($types as $key => $type) {
$result[$key] = array_intersect($type, $objects);
}

$objects = ['car', 'cat', 'dog', 'Peter'];
$types = [
'man' => ['Peter', 'John'],
'animal' => ['pig', 'cat', 'dog'],
'vehicle' => ['bus', 'car']
];
foreach ($types as $key => $type) {
$result[$key] = array_intersect($type, $objects);
}
echo '<pre>';
print_r($result);
Array
(
[man] => Array
(
[0] => Peter
)
[animal] => Array
(
[1] => cat
[2] => dog
)
[vehicle] => Array
(
[1] => car
)
)

Related

How to remove subarray in multidimensional array if exsits the same values in other array

I have two multidimensional arrays:
Array A
(
[0] => Array
(
[reservation_start] => 08:00:00
[reservation_end] => 08:35:00
)
[1] => Array
(
[reservation_start] => 08:35:00
[reservation_end] => 09:10:00
)
[2] => Array
(
[reservation_start] => 09:10:00
[reservation_end] => 09:45:00
)
)
Array B
(
[0] => Array
(
[reservation_start] => 08:00:00
[reservation_end] => 08:35:00
)
[1] => Array
(
[reservation_start] => 08:35:00
[reservation_end] => 09:10:00
)
)
foreach loop:
foreach ($allHours as $key => $value) {
if (in_array($value, $busyHours)) {
unset($allHours[$key]);
}
}
And now I would like to remove from array A values exists in array.
I used unset in foreach, but in each time arrays have different size so it does not work.
EDIT:
Found a problem, it was in my DB, return wrong time. Thank you for help
assuming arrays A = allhours B = busyhours
stringfy both & reduce to 1-dimensional array
foreach ($all as $k=>$arr) {
$all_copy[$k] = $arr['reservation_start'] . $arr['reservation_end'];
}
foreach ($busy as $k=>$arr) {
$busy_copy[$k] = $arr['reservation_start'] . $arr['reservation_end'];
}
take array difference (if exist in busy, then remove it from all)
// array_diff preserves keys.
$non_busy = array_diff($all_copy, $busy_copy);
get resultant array from the original all
foreach ($non_busy as $k=>$no_need)
{
$result[$k] = $all[$k];
}
you may unset arrays that you won't need anymore except $result
$array1 = [
[ 'start' => '08:00:00', 'end' => '08:35:00' ],
[ 'start' => '08:35:00', 'end' => '09:10:00' ],
[ 'start' => '09:10:00', 'end' => '09:45:00' ]
];
$array2 = [
[ 'start' => '08:00:00', 'end' => '08:35:00' ],
[ 'start' => '08:35:00', 'end' => '09:10:00' ]
];
$result = [];
array_walk($array1, function ($value1) use (&$result, $array2) {
if(!array_filter($array2, fn($item2) => $value1 == $item2)) {
$result[] = $value1;
}
});

PHP parse array and count values in new array

I have a PHP array that looks like this...
$array = [
'item1' => [
[
'productCount' => '3',
'value' => 'red',
],
[
'productCount' => '3',
'value' => 'green',
],
[
'productCount' => '3',
'value' => 'green',
]
],
'item2' => [
[
'productCount' => '1',
'value' => 'purple',
]
],
];
I am trying to parse it so it looks like this...
Array
(
[item1] => Array
(
[productCount] => 3
[red] => 1
[green] => 2
)
[item1] => Array
(
[productCount] => 1
[purple] => 1
)
)
I have this so far....
$finalArray = array();
foreach ($array as $key => $arrayItem) {
$finalArray[$key] = $arrayItem['productCount'];
$valueCount = count($arrayItem['productCount']);
$finalArray[$key] = $valueCount;
}
I know this isn't much but I am stuck at this point. How do I process the values and count them in the new array?
This code will give you the results you want. It loops over the upper level array to get the keys and productCount values for the new array. Then it loops over the second level arrays to get the counts of each value:
$output = array();
foreach ($array as $key => $items) {
$output[$key] = array('productCount' => $items[0]['productCount']);
foreach ($items as $item) {
$value = $item['value'];
$output[$key][$value] = ($output[$key][$value] ?? 0) + 1;
}
}
print_r($output);
The inner loop can be written more concisely using array_column and array_count_values:
$output = array();
foreach ($array as $key => $items) {
$output[$key] = array_merge(array('productCount' => $items[0]['productCount']),
array_count_values(array_column($items, 'value')));
}
print_r($output);
In both cases the output is:
Array
(
[item1] => Array
(
[productCount] => 3
[red] => 1
[green] => 2
)
[item2] => Array
(
[productCount] => 1
[purple] => 1
)
)
Demo on 3v4l.org
For dynamic get all result use two times foreach loops
$array = [
'item1' => [
[
'productCount' => '3',
'value' => 'red',
],
[
'productCount' => '3',
'value' => 'green',
],
[
'productCount' => '3',
'value' => 'green',
]
],
'item2' => [
[
'productCount' => '1',
'value' => 'purple',
]
],
];
$new_array = $final_array = array();
foreach ($array as $key => $arrayItem) {
foreach($arrayItem as $sub_key=>$second_item){
$new_array[$key]['productCount'] = $second_item['productCount'];
$new_array[$key][$second_item['value']][] =$second_item['value'];
}
}
foreach ($new_array as $key => $value) {
foreach($value as $sub_key =>$sub_value){
$final_array[$key][$sub_key] = (is_array($sub_value))?count($sub_value):$sub_value;
}
}
print_r($final_array);exit;
Output
Array
(
[item1] => Array
(
[productCount] => 3
[red] => 1
[green] => 2
)
[item2] => Array
(
[productCount] => 1
[purple] => 1
)
)
Hope this is helpful to you.

Php sort multiple array using concretely values

I have array such as:
$arr = [
0=>['note_id'=>1,'content'=>1],
1=>['note_id'=>2,'content'=>2],
2=>['note_id'=>3,'content'=>3],
];
And I have array of ids:
$ids=[2,3,1];
I need get new array from arr by using the sorting this array by value 'note_id' and array ids, so resut must be:
$arr = [
1=>['note_id'=>2,'content'=>2],
2=>['note_id'=>3,'content'=>3],
0=>['note_id'=>1,'content'=>1],
];
Are there any functions for this? Thanks!
You could loop both the arrays and compare the keys of $arr with with the values of $ids and create your new array $newArr.
$arr = [
0 => ['note_id' => 1, 'content' => 1],
1 => ['note_id' => 2, 'content' => 2],
2 => ['note_id' => 3, 'content' => 3],
];
$ids = [2, 3, 1];
$newArr = [];
foreach ($ids as $id) {
foreach ($arr as $keyArr => $item) {
if ($id === $item['note_id']) {
$newArr[$keyArr] = $item;
}
}
}
print_r($newArr);
Result:
Array
(
[1] => Array
(
[note_id] => 2
[content] => 2
)
[2] => Array
(
[note_id] => 3
[content] => 3
)
[0] => Array
(
[note_id] => 1
[content] => 1
)
)
Demo

Search in multidimensional array by key and return the sub array

I have multidimensional array and i want to extract a sub array by its key.
Example array:
[libra] => Array
(
[schema_id] => LibraModel
[libra_guid] => a2d02184-5a83-0f1b-673d-7f215fe6ba02
[is_test_client] =>
[is_web_bot] =>
[tag_collection] => Array
(
[schema_id] => TestGroupAssignmentModel
[tags_by_test] => Array
(
[checked] => Array
(
[first] => Tester
[second] => de11e041-1083-44bb-96dc-134fa099f737
[control] => false
)
[optionSelected] => Array
(
[schema_id] => TestGroupAssignmentModel
[test_group_guid] => 6a28c568-a416-4d3a-a993-4eb7f6ce19d3
[control] =>
[test_name_hash] => ecdd6bf92e27aa10ca5e3acbe385fb6b
[fully_qualified_hash] => 9e97e3244516f219887294435975df22
[do_not_track] =>
)
)
)
)
From this array i want to get only the optionSelected, and keep it's structure.
Best function i did so far is this:
$multi_array is the array displayed on above,
$array_key is string 'optionSelected'
$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($multi_array));
foreach($iterator as $key => $value) {
if($array_key == $key){
echo $key;
}
}
This should get the job done:
<?php
$array = [
'test' => 'value',
'level_one' => [
'level_two' => [
'level_three' => [
'replace_this_array' => [
'special_key' => 'replacement_value',
'key_one' => 'testing',
'key_two' => 'value',
'four' => 'another value'
]
],
'ordinary_key' => 'value'
]
]
];
$recursiveIterator = new \RecursiveIteratorIterator(
new \RecursiveArrayIterator($array),
\RecursiveIteratorIterator::SELF_FIRST
);
$extractKey = "level_three";
$result = [];
foreach ($recursiveIterator as $key => $value) {
if ($key === $extractKey) {
$result = $value;
}
}
var_dump($result);
Thanks to the \RecursiveIteratorIterator::SELF_FIRST the $value will always contain the whole sub array.

Array within array as single associative array

I am having array within array values as below.
Array
(
[0] => Array
(
[0] => Array
(
[Floor] => Floor-1
)
[1] => Array
(
[Flat] => Flat A2
)
[2] => Array
(
[Area] => Balcony,
)
)
)
I need to make it as single associative array as below.
Array
(
[0] => Array
(
[Floor] => Floor-1
[Flat] => Flat A2
[Area] => Balcony,
)
)
How can i do this ?
This example should help you.
<?php
$arr = array(
array(
'floor'=>'Floor-1'
),
array(
'Flat'=>'Flat A2'
),
array(
'Area'=>'Balcony,'
),
);
$final_array = array();
foreach ($arr as $arr1) {
foreach ($arr1 as $key => $value) {
$final_array[$key] = $value;
}
}
?>
Output will be
Array
(
[floor] => Floor-1
[Flat] => Flat A2
[Area] => Balcony,
)
Here we have created an empty array called as $final_array we will append this array by using foreach loop.
Remember, if you have a same array key then the last value will overwrite like below.
<?php
$arr = array(
array(
'floor'=>'Floor-1',
'floor'=>'Floor-2',
),
array(
'Flat'=>'Flat A2'
),
array(
'Area'=>'Balcony,'
),
array(
'Area'=>'Balcony2,'
),
);
$final_array = array();
foreach ($arr as $arr1) {
foreach ($arr1 as $key => $value) {
$final_array[$key] = $value;
}
}
?>
Now, output will be
Array
(
[floor] => Floor-2
[Flat] => Flat A2
[Area] => Balcony2,
)
<?php
$array = [
[
[
'foo' => 'big'
],
[
'bar' => 'fat'
],
[
'baz' => 'mamma'
]
]
];
$merged[0] = array_reduce($array[0], function($carry, $item) {
return array_merge((array) $carry, $item);
});
var_export($merged);
Output:
array (
0 =>
array (
'foo' => 'big',
'bar' => 'fat',
'baz' => 'mamma',
),
)
This single line code is enough to do this
$newArr = call_user_func_array('array_merge',$dataArr); ///where $dataArr is your array..
call_user_func_array will call a callback function with array of parameters and array_merge will merge all these parameters in single array read more about call_user_func_array() and array_merge()
Example code:
<?php
$dataArr = array(
array(
'Floor'=>'Floor-1'
),
array(
'Flat'=>'Flat A2'
),
array(
'Area'=>'Balcony,'
),
);
$newArr = call_user_func_array('array_merge',$dataArr);
echo "<pre>"; print_r($newArr);
?>
This will give you :
Array
(
[Floor] => Floor-1
[Flat] => Flat A2
[Area] => Balcony,
)

Categories