Delete array from nested array - php

How can I delete the first Name arrray
[0] => Array
(
[Name] => John
)
from this one just if exist at lest two Name objects?
Array
(
[0] => Array
(
[Name] => John
)
[1] => Array
(
[Name] => James
)
[2] => Array
(
[Surname] => Doe
)
)
I'm trying to go through array with foreach, count how many arrays has name object and if there is more than one, then unset the first, but I'm not able to do that:
foreach($endArray as $arr)
{
if(count($arr['Name'])>1)
{
unset($endArray[0]);
}
}

In your code you use if(count($arr['Name'])>1) but I think that will never be true as the count will return 1 when the value is neither an array nor an object with implemented Countable interface.
To unset the first when there are more than one, you could count the number of occurrences of "Name" in the items using array_column.
If you want to remove the first array which has a key "Name" you could loop over the items and use unset using the $key.
Then break the loop to only remove the first encounter item.
$endArray = [
["Name" => "John"],
["Name" => "James"],
["Name" => "Doe"]
];
if (count(array_column($endArray, 'Name')) > 1) {
foreach ($endArray as $key => $arr) {
if (array_key_exists('Name', $arr)) {
unset($endArray[$key]);
break;
}
}
}
print_r($endArray);
Php demo
Output
Array
(
[1] => Array
(
[Name] => James
)
[2] => Array
(
[Name] => Doe
)
)
Another option is to keep track of the number of times the "Name" has been encountered:
$count = 0;
foreach ($endArray as $key => $arr) {
if (array_key_exists('Name', $arr) && $count === 0) {
$count++;
} else {
unset($endArray[$key]);
break;
}
}
Php demo

Related

Remove subsets from each row where the same subset is found in another row

I need to remove objects from a 3d array where the same two-property object is found in any other row.
I previously asked this similar question, but my new requirements are slightly different because I was keeping one of the encountered duplicates. Now I would like for both/all encountered duplicates to be removed.
[
[
["name" => "John", "surname" => "Smith"],
["name" => "Kate", "surname" => "Winston"]
],
[
["name" => "Kate", "surname" => "Winston"],
["name" => "Jack", "surname" => "Irving"]
],
]
Desired filtered result with same original structure:
[
[
["name" => "John", "surname" => "Smith"],
],
[
["name" => "Jack", "surname" => "Irving"]
],
]
Seems like others answers don't see their own final results and don't read desired output.
Here a little bit hard solution but it works well.
Note: the input data array must have 2 object indexes and 2 arrays of objects for comparing, otherwise, it should be fixed.
$ar = Array (
0 => [(object)["name"=>"John", "surname"=>"Smith"], (object)["name"=>"Kate", "surname"=>"Winston"]],
1 => [(object)["name"=>"Kate", "surname"=>"Winston"], (object)["name"=>"Jack", "surname"=>"Irving"]]
);
$arr = [];
$k = 0; // do `if statement` only once
foreach($ar as $num=>&$subar){
foreach($subar as $num2=>$pers){
$subar[$num2] = (array)$pers; // object to array
if (!$k) {
$keys = array_keys($subar[$num2]); // collect "name" and "surname" in an array
$k++;
}
foreach($subar[$num2] as $a=>$b){
$seq = array_search($a,$keys); // index of the current key
if (!$seq) { // 0 -> "name", 1 -> "surname"
$arr[$num][$b] = '';
} else {
$arr[$num][$subar[$num2][current($keys)]] = $b;
}
}
}
}
$diff[] = array_diff($arr[0],$arr[1]); // clear duplicates from 1-st set
$diff[] = array_diff($arr[1],$arr[0]); // clear duplicates from 2-nd set
Gives result:
Array
(
[0] => Array
(
[John] => Smith
)
[1] => Array
(
[Jack] => Irving
)
)
And after you can re-create the output array:
// creating a new array
$res = [];
foreach($diff as $num=>$ns){
foreach($ns as $name=>$surname){
foreach($keys as $ind=>$key){
if ($ind % 2 == 0){
$tmp[$key] = $name; // put name
} else {
$tmp[$key] = $surname; // put surname
}
}
$res[$num] = (object)$tmp; // array to object
}
}
Output will be:
Array
(
[0] => stdClass Object
(
[name] => John
[surname] => Smith
)
[1] => stdClass Object
(
[name] => Jack
[surname] => Irving
)
)
Demo
In case of string values in the input arrays, i.e.:
$ar = [
'[{"name":"John", "surname":"Smith"}, {"name":"Kate", "surname":"Winston"}]',
'[{"name":"Kate", "surname":"Winston"}, {"name":"Jack", "surname":"Irving"}]'
];
You need a little fix:
...
foreach($ar as $num=>&$subar){
$ar[$num] = json_decode($subar);
foreach($subar as $num2=>$pers){
...
The same output you will get.
Demo
It's easier if you don't trim away the brackets [], as you stated that you did in the comments. That way, they are proper JSON strings, which we can use in PHP.
Map (or loop) over your array, and build up a $result array, where you append all the arrays from your decoded JSON. Once you have your final $result, you have an array that looks somewhat like
Array (
[0] => Array
(
[name] => John
[surname] => Smith
)
[1] => Array
(
[name] => Kate
[surname] => Winston
)
[2] => Array
(
[name] => Kate
[surname] => Winston
)
[3] => Array
(
[name] => Jack
[surname] => Irving
)
)
We have all the values in an actual array now, but there are duplicates -- which can be removed using array_unique() with the SORT_REGULAR flag.
$array = [
'[{"name":"John", "surname":"Smith"}, {"name":"Kate", "surname":"Winston"}]',
'[{"name":"Kate", "surname":"Winston"}, {"name":"Jack", "surname":"Irving"}]'
];
$result = [];
array_map(function($v) use (&$result) {
$result = array_merge($result, json_decode($v, true));
}, $array);
print_r(array_unique($result, SORT_REGULAR));
Final output:
Array
(
[0] => Array
(
[name] => John
[surname] => Smith
)
[1] => Array
(
[name] => Kate
[surname] => Winston
)
[3] => Array
(
[name] => Jack
[surname] => Irving
)
)
Live demo at https://3v4l.org/q6pZc
$array = [
'[{"name":"John", "surname":"Smith"}, {"name":"Kate", "surname":"Winston"}]',
'[{"name":"Kate", "surname":"Winston"}, {"name":"Jack", "surname":"Irving"}]'
];
$resultArray = [];
foreach ($array as $item) {
$bufferArray = array_merge($resultArray, json_decode($item));
foreach ($bufferArray as $elements) {
$key = $elements->name . $elements->surname;
if (array_key_exists($key, $resultArray)) {
unset($resultArray[$key]);
} else {
$resultArray[$key] = $elements;
}
}
}
print_r($resultArray);
Output
Array
(
[KateWinston] => stdClass Object
(
[name] => Kate
[surname] => Winston
)
[JackIrving] => stdClass Object
(
[name] => Jack
[surname] => Irving
)
)
can rewrite this into more serious code )
To remove objects from each row where a given object exists any where in any other row, you can make iterates calls of array_udiff(). Inside the function, the first parameter should be the currently iterated row and the next/subsequent parameter(s) should all of the other rows in the entire array. The last parameter is the callback which compares whole objects to whole objects via PHP's performance-optimized algorithm.
My snippet below will not only handle your 2-row array, it will also handle arrays with 3 or more rows.
Code: (Demo)
$result = [];
foreach ($array as $i => $objs) {
$cache = $array[$i];
unset($array[$i]);
$params = [
$objs,
...$array,
fn($a, $b) => $a <=> $b
];
$result[] = array_udiff(...$params);
$array[$i] = $cache;
}
var_export($result);
To be clear, this snippet will work the same if the array of arrays of objects is an array of arrays of arrays.

Pushing a sub array into the same array

I am trying to put content of one array into the same array. Here I have an array $mclass with values such as
Array
(
[0] => stdClass Object
(
[room_id] => 1,3,5
[day] => 1
[class_teacher] => TEA-2014-2
[final_exam_date] => 2015-09-21
)
)
You can see I have room_id index with 1,3,5 value. Now, I want to explode the room_id and get duplicate of same array index data with change of room_id and push into the array. and finally delete the current array index such as [0]. Here I want the final result as.
Array
(
[0] => stdClass Object
(
[room_id] => 1
[day] => 1
[class_teacher] => TEA-2014-2
[final_exam_date] => 2015-09-21
)
[1] => stdClass Object
(
[room_id] => 3
[day] => 1
[class_teacher] => TEA-2014-2
[final_exam_date] => 2015-09-21
)
[2] => stdClass Object
(
[room_id] => 5
[day] => 1
[class_teacher] => TEA-2014-2
[final_exam_date] => 2015-09-21
)
)
Here is my code for the same:
if(count($mclass)>0)
{
foreach($mclass as $mclasskey=>$mclass_row)
{
/* Room ID Calculation */
if(isset($mclass[$mclasskey]))
{
$temp_room_id = explode(',',$mclass_row->room_id);
if(count($temp_room_id)>1)
{
foreach($temp_room_id as $trkey=>$tr)
{
if(!in_array($temp_room_id[$trkey], $morning_class_semester))
{
array_push($morning_class_semester,$temp_room_id[$trkey]);
}
}
if(count($morning_class_semester)>0)
{
foreach($morning_class_semester as $mcskey=>$mcs)
{
$index_count = count($new_test);
$test[$index_count] = $mclass[$mclasskey];
$test[$index_count]->room_id = $morning_class_semester[$mcskey];
array_push($new_test,$test[$index_count]);
}
unset($mclass[$mclasskey]);
}
}
}
}
}
The code below does what you're looking for using only arrays. So you'll have to change the array access operators to -> since you're accessing an object. I'd do so, but it would break the example, so I'll leave that up to you.
Code Explained:
Loop through array selecting each subarray (object in your case), explode on the $item('room_id') ... ($item->room_id in your case) ... and create sub arrays, via loop, from that using the data from the original using each key. Remove the original item (which has the combined room_ids) and combine the placeholder and original array.
<?php
//Establish some data to work with
$array = array(
array(
"room_id" => "1,3,5",
"day" => 1,
"class_teacher" => "TEA-2014-2",
"final_exam_date" => "2015-09-21",
));
foreach ($array as $key => $item) {
$placeholder = array();
$ids = explode(',',$item['room_id']);
if (count($ids) > 1) {
foreach ($ids as $id) {
$push = array(
'room_id' => $id,
'day' => $item['day'],
'class_teacher' => $item['class_teacher'],
'final_exam_date' => $item['final_exam_date']
);
array_push($placeholder, $push);
}
$array = array_merge($array, $placeholder);
unset($array[$key]);
}
}
var_dump($array);
?>

Combine two arrays into a single array based on a common column value

I am trying to combine two arrays while respecting their shared value.
$array1 = array(
array("id" => "1","name"=>"John"),
array("id" => "2","name"=>"Peter"),
array("id" => "3","name"=>"Tom"),
array("id" => "12","name"=>"Astro")
);
$array2 = array(
array("id" => "1","second_name"=>"Lim"),
array("id" => "2","second_name"=>"Parker"),
array("id" => "3","second_name"=>"PHP")
);
My expected output:
$result = array(
array("id" => "1","name"=>"John","second_name"=>"Lim"),
array("id" => "2","name"=>"Peter","second_name"=>"Parker"),
array("id" => "3","name"=>"Tom","second_name"=>"PHP"),
array("id" => "12","name"=>"Astro")
);
I have made a try by
$arraycomb = array_unique(array_merge($array1,$array2), SORT_REGULAR);
My output is:
Array
(
[0] => Array
(
[id] => 1
[name] => John
)
[1] => Array
(
[id] => 2
[name] => Peter
)
[2] => Array
(
[id] => 3
[name] => Tom
)
[3] => Array
(
[id] => 12
[name] => Astro
)
[4] => Array
(
[id] => 1
[second_name] => Lim
)
[5] => Array
(
[id] => 2
[second_name] => Parker
)
[6] => Array
(
[id] => 3
[second_name] => PHP
)
)
How can I combine the key value inside same array? or how can I bring the expected output?
Note: I am trying for value instead of key ref: PHP Array Merge two Arrays on same key
Alternatively, you could use a foreach in this case then merge them if they share the same id key
With using reference &
foreach($array1 as &$value1) {
foreach ($array2 as $value2) {
if($value1['id'] == $value2['id']) {
$value1 = array_merge($value1, $value2);
}
}
}
echo '<pre>';
print_r($array1);
You can use array_map() for this. Try this -
function modifyArray($a, $b)
{
if (!empty($a) && !empty($b)) {
return array_merge($a, $b);
} else if (!empty($a) && empty($b)) {
return $a;
} else if (empty($a) && !empty($b)) {
return $b;
}
}
$new = array_map("modifyArray", $array1, $array2);
var_dump($new);
It will generate the new array will all the values in both arrays.if the first array's element is empty then the second array will be merged and vice-versa.
Assign temporary first level keys to your first array to aid in identifying rows. Then loop the second array and append the desired column value to the appropriate group. Re-index the array after looping with array_values().
Code: (Demo)
$result = array_column($array1, null, 'id');
foreach ($array2 as $row) {
$result[$row['id']]['second_name'] = $row['second_name'];
}
var_export(array_values($result));
This is a more direct approach than brute force scanning arrays with nested loops.
If all ids in the second array exist in the first array, then the following simpler line can be written inside the body of the foreach().
$result[$row['id']] += $row;

Convert complex numerical array to associative array

I have an array data that look like this :
Array (
[0] => Array (
[0] => Name:
[1] => John W.
[2] => Registration ID:
[3] => 36
)
[1] => Array (
[0] =>Age:
[1] => 35
[2] => Height:
[3] => 5'11"
)
[3] => Array (
[0] => Sex:
[1] => M
[2] => Weight:
[3] => 200lbs
)
[4] => Array (
[0] => Address
)
[5] => Array (
[0] => 6824 crestwood dr delphi, IN 46923
))
And I want to convert it to associative array like this :
Array(
['Name']=> John W.
['Registration ID']=> 36
['Age']=> 35
['Height'] => 5'11''
['Sex']=>M
['Weight']=>200lbs
['Address']=>6824 crestwood dr delphi, IN 46923
)
I have no idea at all how to do this, since the supposed to be array column header were also in sequence, so it makes difficult to convert this array.
Any help I appreciate, thx.
Given your origin array is called $origin , you can do it like this:
$merged = array();
foreach($origin as $val) {
$merged = array_merge($merged, $val);
}
$tot = count($merged) - 1;
for ($i=0;$i<$tot;$i+=2) {
$result[$merged[$i]] = $merged[$i+1];
}
var_dump($result); // To test the resulting array
Firstly, I use array_merge() to flatten the $origin array to only one dimension/depth, so we later iterate it (stepping each 2 items per iteration) and assigning each pair of items ($i and $i+1) to the resulting array.
Looks like, for the first 3 children, you can just assign the even value to the previous element as key. Then, assign the fourth one as key for fifth element.
$result = array();
foreach ($array as $key => $value)
{
if ($key < 4) {
$elements = array_values($value);
$result[$elements[0]] = $elements[1];
$result[$elements[2]] = $elements[3];
}
if ($key == 4)
$fifthkey = $value;
if ($key == 5)
$result[$fifthkey] = $value;
}
Also, note that you have to escape your height string quotes.

Checking if array value exists in a PHP multidimensional array

I have the following multidimensional array:
Array ( [0] => Array
( [id] => 1
[name] => Jonah
[points] => 27 )
[1] => Array
( [id] => 2
[name] => Mark
[points] => 34 )
)
I'm currently using a foreach loop to extract the values from the array:
foreach ($result as $key => $sub)
{
...
}
But I was wondering how do I see whether a value within the array already exists.
So for example if I wanted to add another set to the array, but the id is 1 (so the person is Jonah) and their score is 5, can I add the 5 to the already created array value in id 0 instead of creating a new array value?
So after the loop has finished the array will look like this:
Array ( [0] => Array
( [id] => 1
[name] => Jonah
[points] => 32 )
[1] => Array
( [id] => 2
[name] => Mark
[points] => 34 )
)
What about looping over your array, checking for each item if it's id is the one you're looking for ?
$found = false;
foreach ($your_array as $key => $data) {
if ($data['id'] == $the_id_youre_lloking_for) {
// The item has been found => add the new points to the existing ones
$data['points'] += $the_number_of_points;
$found = true;
break; // no need to loop anymore, as we have found the item => exit the loop
}
}
if ($found === false) {
// The id you were looking for has not been found,
// which means the corresponding item is not already present in your array
// => Add a new item to the array
}
you can first store the array with index equal to the id.
for example :
$arr =Array ( [0] => Array
( [id] => 1
[name] => Jonah
[points] => 27 )
[1] => Array
( [id] => 2
[name] => Mark
[points] => 34 )
);
$new = array();
foreach($arr as $value){
$new[$value['id']] = $value;
}
//So now you can check the array $new for if the key exists already
if(array_key_exists(1, $new)){
$new[1]['points'] = 32;
}
Even though the question is answered, I wanted to post my answer. Might come handy to future viewers. You can create new array from this array with filter then from there you can check if value exist on that array or not. You can follow below code. Sample
$arr = array(
0 =>array(
"id"=> 1,
"name"=> "Bangladesh",
"action"=> "27"
),
1 =>array(
"id"=> 2,
"name"=> "Entertainment",
"action"=> "34"
)
);
$new = array();
foreach($arr as $value){
$new[$value['id']] = $value;
}
if(array_key_exists(1, $new)){
echo $new[1]['id'];
}
else {
echo "aaa";
}
//print_r($new);

Categories