i have the following problem. i have a large array structure which i assign values from a sql statement:
$data[$user][$month]['id'] = $data->id;
$data[$user][$month]['company'] = $data->company;
...
...
and around 30 other values.
i need to clone this array ($data) and add a subarray like:
$data[$user][$month][$newsubarray]['id'] = $data->id;
$data[$user][$month][$newsubarray]['company'] = $data->company;
...
...
i need to clone it because the original array is used by many templates to display data.
is there a way to clone the array and add the subarray without assign all the values to the cloned array? this blows up my code and is very newbi, but works.
You can use array_map, check the live demo
if you want to pass parameter to array_map(), use this
array_map(function($v) use($para1, $para2, ...){...}, $array);
Here is the code,
<?php
$array =array('user'=> array('month'=>array('id' =>2, 'company' => 3)));
print_r($array);
print_r(array_map(function($v){
$arr = $v['month'];
$v['month'] = [];
$v['month']['newsubarray'] = $arr;
return $v;}
, $array));
You can iterate through the array with nested foreach loops.
It would look similar to this:
foreach ($data as $user=>$arr2) {
foreach ($arr2 as $month=>$arr3) {
foreach ($arr3 as $key=>$value) {
$data[$user][$month][$newsubarray][$key] = $value;
}
}
}
Your last level of array, you can create object, for holding data with implementing ArrayAccess. Then simply by reference, assign object in desire places. This way, you can hold 1 object and use it multi places, but if you change in one - this change in all.
Then you addictionaly, can implements __clone method to clone object correctly.
Related
I have an array of arrays, and I am trying to foreach loop through and insert new item into the sub arrays.
take a look below
$newarray = array(
array("id"=>1,"quantity"=>2),
array("id"=>1,"quantity"=>2),
array("id"=>1,"quantity"=>2),
);
foreach($newarray as $item){
$item["total"] = 9;
}
echo "<br>";
print_r($newarray);
The result just give me the original array without the new "total". Why ?
Because $item is not a reference of $newarray[$loop_index]:
foreach($newarray as $loop_index => $item){
$newarray[$loop_index]["total"] = 9;
}
The foreach() statement gives $item as an array: Not as the real value (consuming array). That meaning it can be read but not changed unless you then overwrite the consuming array.
You could use the for() and loop through like this: see demo.
Note: This goes all the way back to scopes, you should look into that.
While I map all the links on a page that is contained in an array, I want to check if each of the links is inserted in this array and, if not, insert it.
I'm trying to use the code bellow without success because "foreach $arr" doesn't pass by in the new values.
include_once('simple_html_dom/simple_html_dom.php');
$arr = array('http://www.domain.com');
foreach ($arr as $key => &$item) {
$html = file_get_html($item);
// Find category links
foreach($html->find('a[href^=http://www.domain.com/dep/]') as $element) {
if (!in_array($element->href, $arr))
$arr[] = $element->href;
}
}
print_r($arr);
Important: I need to search and add value in the original array, not in the copy (foreach).
First of all
In foreach ($arr as $key => &$item) { every $item is a STRING. (As a warning told you). So you shouldn't use $item[] here.
Next pitfall: if you want to add new items to your $arr array symtax should be
$arr[] = $some_var;
But you shouldn't do this because every time you add items to $arr, this array increases and you iterate not over two elements array, but for example 3-elements or 4 elements. Do you expect this?
You should find new values, put them in some other array and then merge both arrays.
Or use #splash58 solution. It's even simplier.
I can't find an answer to this anywhere.
foreach ($multiarr as $array) {
foreach ($array as $key=>$val) {
$newarray[$key] = $val;
}
}
say $key has duplicate names, so when I am trying to push into $newarray it actually looks like this:
$newarray['Fruit'] = 'Apples';
$newarray['Fruit'] = 'Bananas';
$newarray['Fruit'] = 'Oranges';
The problem is, the above example just replaces the old value, instead of pushing into it.
Is it possible to push values like this?
Yes, notice the new pair of square brackets:
foreach ($multiarr as $array) {
foreach ($array as $key=>$val) {
$newarray[$key][] = $val;
}
}
You may also use array_push(), introducing a bit of overhead, but I'd stick with the shorthand most of the time.
I'll offer an alternative to moonwave99's answer and explain how it is subtly different.
The following technique unpacks the indexed array of associative arrays and serves each subarray as a separate parameter to array_merge_recursive() which performs the merging "magic".
Code: (Demo)
$multiarr = [
['Fruit' => 'Apples'],
['Fruit' => 'Bananas'],
['Fruit' => 'Oranges'],
['Veg' => 'Carrot'],
//['Veg' => 'Leek'],
];
var_export(
array_merge_recursive(...$multiarr)
);
As you recursively merge, if there is only one value for a respective key, then a subarray is not used, if there are multiple values for a key, then a subarray is used.
See this action by uncommenting the Leek element.
p.s. If you know that you are only targetting a single column of data and you know the key that you are targetting, then array_column() would be a wise choice.
Code: (Demo)
var_export(
['Fruit' => array_column($multiarr, 'Fruit')]
);
foreach ($topicarray as $key=>$value){
$files = mysql_query("mysqlquery");
while($file = mysql_fetch_array($files)){ extract($file);
$topicarray[$value] = array( array($id=>$title)
);
}
}
The first foreach loop is providing me with an array of unique values which forms a 1-dimensional array.
The while loop is intended to store another array of values inside the 1-dimensional array.
When the while loop returns to the beginning, it is overwriting it. So I only ever get the last returned set of values in the array.
My array ends up being a two dimensional array with only one value in each of the inner arrays.
Feels like I'm missing something very basic here - like a function or syntax which prevents the array from overwriting itself but instead, adds to the array.
Any ideas?
Step 1. Replace $topicarray[$value] with $topicarray[$value][]
Step 2. ???
Step 3. Profit
Make $topicarray[$value] an array of rows, instead of one row. Also, don't use extract here.
foreach ($topicarray as $key => $value) {
$rows = array();
$files = mysql_query("mysqlquery");
while($file = mysql_fetch_array($files)) {
$rows[] = array($file['id'] => $file['title']);
}
$topicarray[$value] = $rows;
}
Also, you should switch to PDO or MySQLi.
How can you do this? My code seen here doesn't work
for($i=0;i<count($cond);$i++){
$cond[$i] = $cond[$i][0];
}
It can be as simple as this:
$array = array_map('reset', $array);
There could be problems if the source array isn't numerically index. Try this instead:
$destinationArray = array();
for ($sourceArray as $key=>$value) {
$destinationArray[] = $value[0]; //you may want to use a different index than '0'
}
// Make sure you have your first array initialised here!
$array2 = array();
foreach ($array AS $item)
{
$array2[] = $item[0];
}
Assuming you want to have the same variable name afterwards, you can re-assign the new array back to the old one.
$array = $array2;
unset($array2); // Not needed, but helps with keeping memory down
Also, you might be able to, dependant on what is in the array, do something like.
$array = array_merge(array_values($array));
As previously stated, your code will not work properly in various situation.
Try to initialize your array with this values:
$cond = array(5=>array('4','3'),9=>array('3','4'));
A solution, to me better readable also is the following code:
//explain what to do to every single line of the 2d array
function reduceRowToFirstItem($x) { return $x[0]; }
// apply the trasnformation to the array
$a=array_map('reduceRowTofirstItem',$cond);
You can read the reference for array map for a thorough explanation.
You can opt also for a slight variation using array_walk (it operate on the array "in place"). Note that the function doesn't return a value and that his parameter is passed by reference.
function reduceToFirstItem(&$x) { $x=$x[0]; }
array_walk($cond, 'reduceToFirstItem');
That should work. Why does it not work? what error message do you get?
This is the code I would use:
$inArr;//This is the 2D array
$outArr = array();
for($i=0;$i<count($inArr);$i++){
$outArr[$i] = $inArr[$i][0];
}