Remove array from multidimentional array using id in php - php

I want to remove array from multidimentional array using base of ID. I tried using foreach loop. But, It is not working.
Any one help me how to remove this?
Thanks.
=> Array :
Array
(
[0] => Array
(
[id] => 11109
[value] => Yes
[field_id] => 234
)
[1] => Array
(
[id] => 11109
[value] => Yes
[field_id] => 237
)
[2] => Array
(
[id] => 11110
[value] => No
[field_id] => 234
)
[3] => Array
(
[id] => 11110
[value] => No
[field_id] => 237
)
[4] => Array
(
[id] => 11111
[value] => No
[field_id] => 237
)
)
From this array, I want to remove array which
field_id is 234 and value is "No" && field_id is 237 and value is
"No".
field_id is 234 and value is "Yes" && field_id is 237 and value is
"Yes".
So, From this array only ID 11111 array is display otherwise all array remove from current array.
Here is my code using I tried to remove array.
foreach ($collection->getData() as $key => $value) {
if(($value['field_id'] == $ids[0] && $value['value'] == "No")){
echo $value['id'];
// exit;
break;
}
echo $value['field_id'];
echo $value['value'];
if(($value['field_id'] == $ids[1] && $value['value'] == "No")){
print_r($collection->getData()[$key]);
unset($collection->getData()[$key]);
unset($collection->getData()[$key-1]);
}
}

You can create a new Multidimensional array , and copy only the values you want to it .
also , when you use break , you get out of the foreach loop completely , i don't think this is the intended behavior , use continue to skip current iteration and test the next element

Is the function getData() returning a copy of the array or a reference? If is is only a copy the unset($collection->getData()[$key]) won't work.
Better you loop over the array as you do, but store all keys you want to delete in side a other array (e.g. $keysToRemove). When the for-each-loop is finished you start to loop the new array $keysToRemove containing all the keys you want to remove and remove then from array.
$keysToRemove = array();
$data = $collection->getData(); // copy or reference?
foreach ($data as $key => $value) {
if(($value['field_id'] == $ids[0] && $value['value'] == "No")){
echo $value['id'].'<br>';
break; // exit the loop? If you want to jump to the next element use "continue"
}
echo $value['field_id'].'<br>';
echo $value['value'].'<br>';
if(($value['field_id'] == $ids[1] && $value['value'] == "No")){
$keysToRemove[$key] = true;
$keysToRemove[$key-1] = true;
}
}
foreach(array_keys($keysToRemove) as $key){
echo '<p>remove key '.$key.' with content <pre>'.print_r($data[$key], true).'</pre></p>';
unset($data[$key]);
}
echo '<p>Result array is<pre>'.print_r($data, true).'</pre></p>';
So you don't manipulate the array your loop use at the moment.

Based on the comment that mentioned its a Magento Collection. I think, You could filter the ids in collection itself so that those are not fetched as part of the collection you want. Like:
$collection = Mage::getModel('your/model')->getCollection();
$collection->addAttributeToFilter('field_id', array('nin' => array(234, 237)));
OR, following if your model is non-eav entity model
$collection = Mage::getModel('your/model')->getCollection();
$collection->addFieldToFilter('field_id', array('nin' => array(234, 237)));

try this code which remove all array value which value is No
$cart = array(
0 => array
(
'id' => 11109,
'value' => 'Yes',
'field_id' => 234
),
1 => array
(
'id' => 11109,
'value' => 'Yes',
'field_id' => 123
),
2 => array
(
'id' => 11110,
'value' => 'No',
'field_id' => 234
),
3 => array
(
'id' => 11110,
'value' => 'No',
'field_id' => 237
),
4 => array
(
'id' => 11111,
'value' => 'No',
'field_id' => 237
),
);
$found = array();
$i = 0;
foreach ($cart as $key => $data) {
if ($data['field_id'] == 234 && $data['value'] == 'No') {
$found[$i]['id'] = $data['id'];
$found[$i]['value'] = $data['value'];
$found[$i]['field_id'] = $data['field_id'];
$i++;
}
}
echo "<pre>";
print_r($found);
then Output Is:
Array
(
[0] => Array
(
[id] => 11111
[value] => No
[field_id] => 234
)
)

Related

Group and merge subarray data based on one column value

I have an array in PHP code below, and I want to convert this array to be grouped by data value. It's always hard to simplify arrays.
Original array:
Array
(
[0] => Array
(
[date] => 2017-08-22
[AAA] => 1231
)
[1] => Array
(
[date] => 2017-08-21
[AAA] => 1172
)
[2] => Array
(
[date] => 2017-08-20
[AAA] => 1125
)
[3] => Array
(
[date] => 2017-08-21
[BBB] => 251
)
[4] => Array
(
[date] => 2017-08-20
[BBB] => 21773
)
[5] => Array
(
[date] => 2017-08-22
[CCC] => 3750
)
[6] => Array
(
[date] => 2017-08-20
[CCC] => 321750
)
)
Below is my desired array:
Array
(
[2017-08-22] => Array
(
[AAA] => 1231
[CCC] => 3750
)
[2017-08-21] => Array
(
[AAA] => 1172
[BBB] => 251
)
[2017-08-20] => Array
(
[AAA] => 1125
[BBB] => 21773
[CCC] => 321750
)
)
It is also ok to have empty null value if the data doesn't exist. [BBB] => NULL for 2017-08-22.
Can anybody help? Thanks in advance...
A simple loop should do this..
$group = [];
foreach ($data as $item) {
if (!isset($group[$item['date']])) {
$group[$item['date']] = [];
}
foreach ($item as $key => $value) {
if ($key == 'date') continue;
$group[$item['date']][$key] = $value;
}
}
Here : this should do the work.
$dst_array = array();
foreach ($array as $outerval) {
foreach ($outerval as $key => $innerval) {
if ($key != 'date') {
$dst_array[$outerval['date']][$key] = $innerval;
}
}
}
It iterates through the array and then through the entries in each subarray. Any any that is not a date is assigned in the destination array in the subarray corresponding to its date and with its own current key.
I definitely wouldn't recommend any techniques that involve more than one loop -- this process can certainly be performed in a single loop.
If you like language construct iteration, use a foreach() loop: (Demo)
$result = [];
foreach ($array as $row) {
$date = $row['date'];
unset($row['date']);
$result[$date] = array_merge($result[$date] ?? [], $row);
}
var_export($result);
If you like to use functional programming and fewer global variables, use array_reduce(): (Demo)
var_export(
array_reduce(
$array,
function($accumulator, $row) {
$date = $row['date'];
unset($row['date']);
$accumulator[$date] = array_merge($accumulator[$date] ?? [], $row);
return $accumulator;
},
[]
)
);
These techniques unconditionally push data into the subarray with the key based on the date column value.
The above technique will work consistently even if the order of your subarray elements changes.
The ?? (null coalescing operator) is to ensure that array_merge() always has an array in the first parameter -- if processing the first occurrence of a given date, you simply merge the current iteration's data (what's left of it after unset() removes the date element) with an empty array.
I believe this solution will work for you:
<?php
$array = Array
(
0 => Array
(
'date' => '2017-08-22',
'AAA' => '1231',
),
1 => Array
(
'date' => '2017-08-21',
'AAA' => '1172',
),
2 => Array
(
'date' => '2017-08-20',
'AAA' => '1125'
),
3 => Array
(
'date' => '2017-08-21',
'BBB' => '251'
),
4 => Array
(
'date' => '2017-08-20',
'BBB' => '21773',
),
5 => Array
(
'date' => '2017-08-22',
'CCC' => '3750'
),
6 => Array
(
'date' => '2017-08-20',
'CCC' => '321750'
)
);
echo '<pre>';
$array1 = array('AAA' => null, 'BBB' => null, 'CCC' => null);
$array2 = array();
array_walk($array, function ($v) use (&$array2, $array1) {
$a = $v['date'];
if (!isset($array2[$a])) {
$array2[$a] = $array1;
}
unset($v['date']);
$array2[$a] = array_merge($array2[$a], $v);
});
print_r($array2);
Output
Array
(
[2017-08-22] => Array
(
[AAA] => 1231
[BBB] =>
[CCC] => 3750
)
[2017-08-21] => Array
(
[AAA] => 1172
[BBB] => 251
[CCC] =>
)
[2017-08-20] => Array
(
[AAA] => 1125
[BBB] => 21773
[CCC] => 321750
)
)
check output at: https://3v4l.org/NvLB8
Another approach (quick & dirty) making use of an arrays internal pointer:
$newArray = [];
foreach ($array as $childArray) {
$date = current($childArray);
$value = next($childArray); // this advances the internal pointer..
$key = key($childArray); // ..so that you get the correct key here
$newArray[$date][$key] = $value;
}
This of course only works with the given array structure.
Another perfect usage example for the PHP function array_reduce():
// The input array
$input = array(
0 => array(
'date' => '2017-08-22',
'AAA' => '1231',
),
// The rest of your array here...
);
$output = array_reduce(
$input,
function (array $carry, array $item) {
// Extract the date into a local variable for readability and speed
// It is used several times below
$date = $item['date'];
// Initialize the group for this date if it doesn't exist
if (! array_key_exists($date, $carry)) {
$carry[$date] = array();
}
// Remove the date from the item...
// ...and merge the rest into the group of this date
unset($item['date']);
$carry[$date] = array_merge($carry[$date], $item);
// Return the partial result
return $carry;
},
array()
);
The question is not clear. What is the expected result if one key (AAA f.e) is present on two or more dates? This answer keeps only the last value associated with it.

Send a variable number of POST array variables to their own array

I've got a dynamic form that allows a user to create as many form elements as they need -- then submit them. For this, I have prepared the input names as arrays like
<input name="title[]" ...
and posting them gives me output like
Array
(
[day] => 0
[project_id] => 5
[submit] => publish
[id] => Array
(
[0] => 4
[1] => 5
)
[title] => Array
(
[0] => Step 1
[1] => Step 2
)
[max_vol] => Array
(
[0] => 2
[1] => 3
)
[description] => Array
(
[0] => df dofi dofidfoi
[1] => dfvpdofvdpfo osd pod
)
)
I've created something that allows me to just grab the post arrays like so
foreach( $_POST as $post_key ) {
// ignore non-array post variables
if( is_array( $post_key ) ) {
foreach( $post_key as $form_value ) {
echo "$form_value\n";
}
}
}
/* ouputs...
4
5
Step 1
Step 2
2
3
df dofi dofidfoi
dfvpdofvdpfo osd pod
*/
which nicely sorts the non-arrays from the arrays, but I can't figure out how to take this variable number of created form elements and prepare them into an array variable that looks something like...
Array
(
[0] => Array
(
'id' => 4, 'title' => 'Step 1', 'max_vol' => '2', 'description' => 'df dofi dofidfoi'
),
[1] => Array
(
'id' => 5, 'title' => 'Step 2', 'max_vol' => '3', 'description' => 'dfvpdofvdpfo osd pod'
),
// could be more or less elements...
);
(I will be eventually passing these arrays to a MySQL query builder function).
Thanks.
How about creating a variable that is outside the scope of the foreach loop
$results = array();
foreach( $_POST as $post_key=>$post_value ) {
// ignore non-array post variables
if( is_array( $post_value ) ) {
foreach( $post_value as $form_key=>$form_value ) {
if (!isset($results[$form_key]))
{
$results[$form_key] = array();
}
$results[$form_key][$post_key] = $form_value;
}
}
}
// results is your array variable
print_r($results);
Iterate over some significant $_POST-array key, for example - id and get the values from other $_POST-arrays with the same index:
$values = array();
foreach ($_POST['id'] as $k => $v) {
$values[] = array(
'id' => $v,
'title' => $_POST['title'][$k],
'max_vol' => $_POST['max_vol'][$k],
'description' => $_POST['description'][$k],
);
}
print_r($values);

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);
?>

PHP Replacing Array Value

Im creating an array of products, each with an ID and score:
$savedProducts = array( 'product' => array("product_id" => $product_id,"product_score" => $score));
I want to be able to update the score by using the product_id as identifier.
I've tried:
foreach($savedProducts as $key => $val)
{
if ($val == $property_id )
{
$savedProducts[$key] = $score;
break;
}
}
Which keeps adding a new array item, rather than updating the original.
I think the issue is that my initial array setup then doesn't match the edited one.
Initial array:
Array
(
[product] => Array
(
[product_id] => 125026
[product_score] => 5
)
)
After trying to update score:
Array
(
[0] => Array
(
[product] => Array
(
[product_id] => 125026
[product_score] => 4
)
)
[1] => Array
(
[0] => Array
(
[product] => Array
(
[product_id] => 125026
[product_score] => 4
)
)
)
)
So it keeps addding elements, rather than updating the existing.
with PHP 5.5 use:
$savedProducts = array_column($savedProducts, NULL, 'product_id');
then you can access your product with:
$savedProducts[$product_id]
Please try this
foreach($savedProducts as $key => $val)
{
if($val['product_id'] == $property_id)
{
$savedProperties[$key]['product_score'] = $score;
break;
}
}

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