I am trying to edit a plugin that is fetching a multidimensional array, then breaking it out into a foreach statement and doing stuff with the resulting data.
What I am trying to do is edit the array before it gets to the foreach statement. I want to look and see if there is a key/value combination that exists, and if it does remove that entire subarray, then reform the array and pass it to a new variable.
The current variable
$arrayslides
returns several subarrays that look like something like this (I remove unimportant variables for the sake of briefness):
Array (
[0] => Array (
[slide_active] => 1
)
[1] => Array (
[slide_active] => 0
)
)
What I want to do is look and see if one of these subarrays contains the key slide_active with a value of 0. If it contains a value of zero, I want to dump the whole subarray altogether, then reform the multidimensional array back into the variable
$arrayslides
I have tried a few array functions but have not had any luck. Any suggestions?
$arrayslides = array(0 => array ( 'slide_active' => 1, 'other_data' => "Mark" ),
1 => array ( 'slide_active' => 0, 'other_data' => "ABCDE" ),
2 => array ( 'slide_active' => 1, 'other_data' => "Baker" ),
3 => array ( 'slide_active' => 0, 'other_data' => "FGHIJ" ),
);
$matches = array_filter($arrayslides, function($item) { return $item['slide_active'] == 1; } );
var_dump($matches);
PHP >= 5.3.0
I know its not so efficient but still
foreach ($arraySlides as $key => $value)
{
if(in_array('0', array_values($value))
unset($arraySlides[$key]);
}
Related
When I do a print_r on my $_POST, I have an array that may look like this:
Array
(
[action] => remove
[data] => Array
(
[row_1] => Array
(
[DT_RowId] => row_1
[name] => Unit 1
[item_price] => 150.00
[active] => Y
[taxable] => Y
[company_id] => 1
)
)
)
The row_1 value can be anything formatted like row_?
I want that number as a string, whatever the number is. That key and the DT_RowID value will always be the same if that helps.
Right now I am doing this, but it seems like a bad way of doing it:
//the POST is a multidimensinal array... the key inside the 'data' array has the id in it, like this: row_2. I'm getting the key value here and then removing the letters to get only the id nummber.
foreach ($_POST['data'] AS $key => $value) {
$id_from_row_value = $key;
}
//get only number from key = still returning an array
preg_match_all('!\d+!', $id_from_row_value, $just_id);
//found I had to use [0][0] since it's still a multidimensional array to get the id value
$id = $just_id[0][0];
It works, but I'm guessing there's a faster way of getting that number from the $_POST array.
<?php
$array = [
'data' => [
'row_1' => [],
'row_2' => [],
]
];
$nums = [];
foreach ($array['data'] as $key => $val) {
$nums[] = preg_replace('#[^\d]#', '', $key);
}
var_export($nums);
Outputs:
array (
0 => '1',
1 => '2',
)
Please remember that regular expressions, used in preg_match are not the fastest solution. What I would do is split the string by _ and take the second part. Like that:
$rowId = explode("_", "row_2")[1];
And put that into your loop to process all elements.
This question already has answers here:
Transposing multidimensional arrays in PHP
(12 answers)
Closed 3 months ago.
I am new to php & I'm not sure that this can be done, but I am hoping that someone knows how to. I've collected all the data that I need to submit but now I need to reformat it before I can json_encode to send to the database.
Basically, I have 1 parent array($data) containing 3 sub-arrays ($hours, $WId, $Pid). I need to create associative arrays for each index position & join them together.
Here is my parent array:
$data = array(
'hours' => array(),
'wId' => array(),
'phaseId' => array(),
);
Here is what currently returns when I print_r each of these arrays:
Array ( [hours] => Array ( [0] => 0.5 [1] => 1 [2] => 2 ) )
Array ( [wId] => Array ( [0] => 10, [1] => 9, [2] => 8, ) )
Array ( [phaseId] => Array ( [0] => 20, [1] => 20, [2] => 19, ) )
I need to take these "vertical" arrays & turn them in to "horizontal" arrays per index, using thearray name as the $key & the value for that index as $value. Here is what I need to return.... (Syntax is probably wrong but you can get the idea.)
Array[1] ("hours" => 0.5, "wId" => 10, "phaseId" => 20)
Array[2] ("hours" => 1, "wId" => 9, "phaseId" => 20)
Array[3] ("hours" => 2, "wId" => 8, "phaseId" => 19)
Is there a function that will allow me to do this easily? I saw how to join & merge them together but not sure how to set the array name (hours, etc) as the $key & the value for each index as $value. I need to loop it too because the length of the arrays will vary. (But they will always the same length as each other, so index should still work as what needs to be collected.)
Any suggestions would be greatly appreciated :)
<?php
// set up your output array
$result = array();
// loop through $data, exposing $name for later use
foreach ($data as $name => $array) {
// loop through each named array and set the desired value
// using the current $key and $name
foreach ($array as $key => $value) {
$result[$key][$name] = $value;
}
}
// tada!
print_r($result);
NOTE: In your desired results in your question, you had the parent Array keys starting at 1. This answer assumes that's a typo and you actually wanted them to match the input. If you indeed wanted it to start at one, just change this line in my answer:
$result[$key+1][$name] = $value;
I have an array that contains certain words from a MySQL database, which are matched with words in a line of text. The text is, say, 20 lines long.
The array also stores the position of each word in the database, and some of these words are "related" to other words in the database, which are also stored in the array. It looks a bit like this:
$words = array(
["Line0"] => array (
["Word0"] => array(
["Name"] => "RandomWord",
["DatabasePos"] => 15,
["RelationsInDatabase"] => array (
89, //So this is clearly the same database pos as Word1 on Line0.
27, //let's assume there's a word on line15 that has this database pos
)
),
["Word1"] => array (
["Name"] => "SomeOtherRandomWord",
["DatabasePos"] => 89,
["RelationsInDatabase"] => array (
NULL
)
)
),
["Line1"] => array (
["Word0"] => .... ,
..
...
...
)
);
etc.
I want to iterate through this array, and find the words that are related to by other words. Then, append to the same array which lines and which words they are related to. For example:
$words = array(
["Line0"] => array (
["Word0"] => array(
["Name"] => "RandomWord",
["DatabasePos"] => 15,
["RelationsInDatabase"] => array (
89, //So this is clearly the same database pos as Word1 on Line0.
27, //let's assume there's a word on line15 that has this database pos
),
["RelationsInLinesOfText"] => array ( //I want to loop through and add this element to the array.
[0] => array("Line0", "Word1"),
[1] => array("Line15", "Word3")
)
),
["Word1"] => array (
["Name"] => "SomeOtherRandomWord",
["DatabasePos"] => 89,
["RelationsInDatabase"] => array (
NULL
)
)
),
["Line1"] => array (
["Word0"] => .... ,
..
...
...
)
);
My problem is that I end up with a very messy, 4/5 level deep "foreach" loop and end up making a bunch of mistakes that are hard to debug due to the messy code. Is there a clean way of doing this, maybe using something like a RecursiveArrayIterator? I don't have much experience with PHP iterator objects.
Thanks for the help
It is an ugly solution, but I think in any case you'll need to iterate through entire array twice-nested:
function searchLink($iLink, &$rgData)
{
$rgResult = [];
foreach($rgData as $sLine=>$rgLines)
{
foreach($rgLines as $sWord=>$rgWord)
{
if($rgWord['DatabasePos']==$iLink)
{
$rgResult[]=['line'=>$sLine, 'word'=>$sWord];
}
}
}
return $rgResult;
}
//$rgData is a data array
foreach($rgData as $sLine => $rgLines)
{
foreach($rgLines as $sWord=>$rgWord)
{
foreach($rgWord['RelationsInDatabase'] as $iPosition)
{
$rgData[$sLine][$sWord]['RelationsInLinesOfText'][]=searchLink($iPosition, $rgData);
}
}
}
also, since you've not mentioned if position is unique, an array ['line'=>$sLine, 'word'=>$sWord] will be written to each entry.
I've researched topics similar to this but not exactly what I'm looking to do.
I have a multidimensional array like the following.
[code] => BILL
[assets] => Array
(
[en] => Array
(
[datatype] => My Assets
[data] => Array
(
[Corporate Equity] => 41
[Global Equity] => 24
[Fixed Income – Government] => 22
[Fixed Income – Corporate] => 8.1
[Other] => 3.57
)
)
)
I'd like to remove the first inner array, but preserve the values. Shift them up one level in the array so that it looks like this.
[code] => BILL
[assets] => Array
(
[datatype] => My Assets
[data] => Array
(
[Corporate Equity] => 41
[Global Equity] => 24
[Fixed Income – Government] => 22
[Fixed Income – Corporate] => 8.1
[Other] => 3.57
)
)
This is just the beginning of the array, there are other instances of the same key [en] at the same level.
I've tried unset, array_shift and others but I need to keep the contents of [en], just shift them up one level in the array.
You can use array_map which returns an array which contains all elements of the previous array after applying the function.
In this case it will simply take the array at index en and add it's contents to the new array.
http://php.net/manual/en/function.array-map.php
$arr = array('assets' => array(
'en' => array(
'datatype' => 'My Assets',
'data' => array(
'Corporate Equity' => 41,
'Global Equity' => 24,
'Fixed Income – Government' => 22,
'Fixed Income – Corporate' => 8.1,
'Other' => 3.57
)
)
));
$new_arr = array_map(function ($e) {
return $e['en'];
}, $arr);
A simple solution that assumes the key to always be en and the subkeys to always be (only) datatype and data:
$assets['datatype'] = $assets['en']['datatype'];
$assets['data'] = $assets['en']['data'];
unset( $assets['en'] );
This code could be problematic for you in the future if that array structure ever changes (it lacks extensibility), but it gets you what you want given the information you have provided.
array_shift is the opposite of array_pop. Used in stack/queue like structures for removing the fist element http://php.net/manual/en/function.array-shift.php
What you want to do is flatten the array. But if you want to keep all the other sub-arrays as you mentioned, you might look up array_merge.
I faced the same scenario after using reader to read xml file, the returned array was having inserted 0 key array in each level like the following one:
'config' =>
0 =>
'products' =>
0 =>
'media' =>
.
.
.
so I built a small function to get rid of a specific key and shift up its child's in a two dimensions array, in my case the key was 0. hopping this would help somebody also.
public function clearMaps(&$maps, $readerMaps, $omittedKey)
{
if (is_array($readerMaps)) {
foreach ($readerMaps as $key => $map) {
if ($key !== $omittedKey) {
$maps[$key] = [];
$this->clearMaps($maps[$key], $readerMaps[$key], $omittedKey);
} else {
$this->clearMaps($maps, $readerMaps[$key], $omittedKey);
}
}
} else {
$maps = $readerMaps;
}
}
// $maps: cleaned array, will start as empty array
// $readerMaps: array needs to be cleaned
// $omittedKey: array key to git rid of.
// first call is clearMaps([], $readerMaps, 0);
I'm a bit struggling with the associative arrays in associative arrays. Point is that I always have to drill deeper in an array and I just don't get this right.
$array['sections']['items'][] = array (
'ident' => $item->attributes()->ident,
'type' => $questionType,
'title' => $item->attributes()->title,
'objective' => (string) $item->objectives->material->mattext,
'question' => (string) $item->presentation->material->mattext,
'possibilities' => array (
// is this even neccesary to tell an empty array will come here??
//(string) $item->presentation->response_lid->render_choice->flow_label->response_label->attributes()->ident => (string) $item->presentation->response_lid->render_choice->flow_label->response_label->material->mattext
)
);
foreach ($item->presentation->response_lid->render_choice->children() as $flow_label) {
$array['sections']['items']['possibilities'][] = array (
(string) $flow_label->response_label->attributes()->ident => (string) $flow_label->response_label->material->mattext
);
}
So 'possibilities' => array() contains an array and if I put a value in it like the comment illustrates I get what I need. But an array contains multiple values so I am trying to put multiple values on the position $array['sections']['items']['possibilities'][]
But this outputs that the values are stores on a different level.
...
[items] => Array
(
[0] => Array
(
[ident] => SimpleXMLElement Object
(
[0] => QTIEDIT:SCQ:1000015312
)
[type] => SCQ
...
[possibilities] => Array
(
)
)
[possibilities] => Array
(
[0] => Array
(
[1000015317] => 500 bytes
)
[1] => Array
...
What am trying to accomplish is with my foreach code above is the first [possibilities] => Array is containing the information of the second. And of course that the second will disappear.
Your $array['sections']['items'] is an array of items, so you need to specify which item to add the possibilities to:
$array['sections']['items'][$i]['possibilities'][]
Where $i is a counter in your loop.
Right now you are appending the Arrays to [items]. But you want to append them to a child element of [items]:
You do:
$array['sections']['items']['possibilities'][] = ...
But it should be something like:
$array['sections']['items'][0]['possibilities'][] = ...
$array['sections']['items'] is an array of items, and as per the way you populate the possibilities key, each item will have it's own possibilities. So, to access the possibilities of the item that is being looped over, you need to specify which one from $array['sections']['items'] by passing the index as explained in the first answer.
OR
To make things simpler, you can try
Save the item array (RHS of the first =) to a separate variable instead of defining and appending to the main array at the same time.
Set the possibilities of that variable.
Append that variable to the main $array['sections']['items']
I have:
array[{IsChecked: true, SEC: 0, STP: 0},
{IsChecked: ture ,SEC: 0, STP: 1},
{IsChecked: false, SEC: 1 ,STP: 0}]
How to get each SEC where IsCheked value is true?