i have two arrays :-
$a1=array(1,1,2,3,1);<br>
$a2=array("m","m","s","xl","s");
i want this as output what should i do :-
Array
(
[0] => Array
(
[0] => 1
[1] => m
[2] => 2 //this is count of m
)
[1] => Array
(
[0] => 1
[1] => s
[2] => 1 //this is count of s
)
[2] => Array
(
[0] => 2
[1] => s
[2] => 1 //this is count of s
)
[3] => Array
(
[0] => 3
[1] => xl
[2] => 1 //this is count of xl
)
)
You could do this by looping over your input arrays, and directly putting an element [1, m, 1] into your result array based on the first set of values ($a1[0] and $a1[0]). Then in the next round, you would have to check if your result array already contains an item with the current product id and size - if so, you increment the counter there, if not, you need to create a new element. But checking if such an item already exists is going to be a bit painful then, because basically you would have to loop over all existing items each time again to do so.
I prefer to go with a different, temporary structure first to gather the necessary data, and then transform it into the desired result in a second step.
$a1=array(1,1,2,3,1);
$a2=array("m","m","s","xl","s");
$temp = [];
foreach($a1 as $index => $product_id) {
$size = $a2[$index];
// if an entry for given product id and size combination already exists, then the current
// counter value is incremented by 1; otherwise it gets initialized with 1
$temp[$product_id][$size] = isset($temp[$product_id][$size]) ? $temp[$product_id][$size]+1 : 1;
}
That gives a $temp array of the following form:
array (size=3)
1 =>
array (size=2)
'm' => int 2
's' => int 1
2 =>
array (size=1)
's' => int 1
3 =>
array (size=1)
'xl' => int 1
You see the product id is the key on the top level, then the size is the key on the second level, and the value on the second level is the count for that combination of product id and size.
Now we transform that into your desired result structure:
$result = [];
foreach($temp as $product_id => $size_data) {
foreach($size_data as $size => $count) {
$result[] = [$product_id, $size, $count];
}
}
var_dump($result);
Related
Ok, so this is a bit tricky and I hit a wall.
What I have is an array of grouping options:
Array
(
[0] => Array
(
[9] => sum
[10] => sum
[11] => avg
)
[4] => Array
(
[9] => sum
[10] => sum
[11] => avg
)
[9] => Array
(
[9] => sum
[10] => sum
[11] => avg
)
)
What I am trying to get is an array that looks like this:
Array
(
[0] => Array
(
[4] => Array
(
[9] => Array
(
[9] => sum
[10] => sum
[11] => avg
)
)
)
)
I this example only shows 3 levels deep but I need this to be dynamic as there will be different grouping options available. Some will only be 1 level which is easy but then there will be 2 or more also. The nested levels should always have the same keys as the parent levels.
What I am doing is using this to iterate over the data. The keys are the indexes in the array of the data I am grouping. The issue is, I need the lower levels of grouping to be aware of the other indexes as this is necessary for proper grouping of multiple datasets. This is to try to simplify processing large datasets. I only need to calculate the lowest level (in this example 9) so I can go over the final array to calculate the grouped data for each parent grouping. I'll use key 9 data to build key 4 data and key 4 data to build key 0 data. The reason the keys need to be aware of the parents is that the data is unique to the parent group. $a[0][4][9] is not the same as $a[0], $a[4], $a[9]. I need 9 to know it's dependent on 4 and 4 is dependent on 0.
I'm not sure if PHP can do this or if this even makes sense. Can you dynamically build an array like that?
This is another recursive 'tree', except it is 'one-way' rather than 'multi-way'. i.e. it is a 'linked list'. The 'node data' is only stored in the final node as it is identical in each node.
As usual: Working code at Codepad.org
I found it quite 'interesting' to work out what i should 'initialize' the output with and what to 'recurse' with. Anyway here is the code...
I decided to simplify the code by dealing with some 'special cases' explicitly at the start...
if (count($source) <= 0) {
return array();
}
elseif (count($source) == 1) {
return array(key($source) => current($source));
}
Next, the function that does the work...
/**
* Add all nodes to the 'tree'
*
* #param type $outNode -- a 'reference' to the current node to be added to
* #param type $curKey -- the index of the current node -- need this when overwriting the 'null' value later.
* #param type $source -- a reference to the source array as i do not want a copies to be made
*
* #return array -- current node
*/
function addNode(&$outNode, $curKey, &$source)
{
// get the current node details...
$curKey = key($source);
$curItems = current($source);
// advance to the next source node...
next($source);
// Is this the final node in the list?
if (current($source) !== false) { // more nodes to add. We need to recurse...
$nextKey = key($source);
$outNode[$curKey] = array($nextKey => null);
return addNode($outNode[$curKey], $nextKey, $source); // recurse
}
// add the items to the last node
$outNode[$curKey] = $curItems;
return $outNode;
}
The starting conditions and build the output...
// generated tree in here
$outTree = array();
// I use the key(), current() and next() functions as I use the 'internal' array iterator.
$curKey = key($source);
$curItems = current($source);
$outTree[$curKey] = null; // the 'null' always gets overwritten later.
// build the tree...
$lastNode = addNode($outTree, $curKey, $source);
// show the output...
echo '<pre>';
print_r($outTree);
echo '</pre>';
exit;
Output using the supplied data:
Array
(
[0] => Array
(
[4] => Array
(
[9] => Array
(
[9] => sum
[10] => sum
[11] => avg
)
)
)
)
As you say that this will be dinamically, first you need to know the first index of your array, I call it $last because in the loop is the last used index:
$last = array_search(array_slice($array, 0, 1), $array);
then in $temp you go saving the array definition before and through the loop.
After the loop you need add the value of your deep array (in this case with var_export) and you need add all the finals ) (in this case with str_repeat)
$temp .= var_export($array[$last], true) . str_repeat(')', $i);
and when you have the final string (array definition) just call eval
eval($temp . ';');
See the code:
<?php
$array = Array
(
0 => Array
(
9 => 'sum',
10 => 'sum',
11 => 'avg'
),
4 => Array
(
9 => 'sum',
10 => 'sum',
11 => 'avg'
),
9 => Array
(
9 => 'sum',
10 => 'sum',
11 => 'avg'
)
);
$last = array_search(array_slice($array, 0, 1), $array);
$temp = "\$newArray = ";
$i = 0;
foreach($array as $key => $value) {
$temp .= "array({$key} => ";
$last = $key;
$i++;
}
$temp .= var_export($array[$last], true) . str_repeat(')', $i);
eval($temp . ';');
echo '<pre>';
print_r($newArray);
echo '</pre>';
Output:
Array
(
[0] => Array
(
[4] => Array
(
[9] => Array
(
[9] => sum
[10] => sum
[11] => avg
)
)
)
)
Below is a array generated by a query builder.
$random_array = Array ( [0] => Array ( [text] => A great time was had by all! )
[1] => Array ( [text] => KILL SHOT )
[2] => Array ( [text] => How is it possible)
[3] => Array ( [text] => http://www.youtube.com/watch?v=KwGOZpbxU9g )
[4] => Array ( [text] => http://www.youtube.com/watch?v=KwGOZpbxU9g )
)
Currently i am doing like this to print the random value
print_r(array_rand($random_array,1));
This is printing the array key as 3 or 1 etc(random from above array).I want to print the value of the key and not the key.
e.g I want to print the random value like this "http://www.youtube.com/watch?v=KwGOZpbxU9g" or "A great time was had by all!" instead of 3 or 1 which is printing now.
Is it possible to do this.
You will have one more line of code as shown below:
$array_key = array_rand($random_array,1); //get the key
print_r( $random_array[$array_key] ); //use the key to print value
What about simply calling
$randNumber = rand(0,count($random_array))-1; //index in array starts with 0
print (string) $random_array[$randNumber];
I'm using a SESSION variable to hold items added to an ingredients page. I'm wondering how I can uniquely identify each key in the array.
I'm adding ingredients via the following and it's working fine.
$_SESSION['ingredients'][] = array($_POST['ingredient'],$_POST['qty']);
If I stick a few ingredients in there and print the array I get..
Array ( [0] => 1 [1] => 50 ) Array ( [0] => 2 [1] => 50 ) Array ( [0] => 3 [1] => 50 )
Where 1, 2 and 3 are the ingredient IDs.
I can remove ingredients from the array based on their ID no problem, but if I put the same ingredient in twice I won't be able to distinguish between them. I was wondering if I can add an incremental number to ID the key?
Each of the items in $_SESSION['ingredients'] already has a unique index (starting from 0 in your case). When you print your $_SESSION['ingredients'] array, you should get this:
Array ( [0] => Array ( [0] => 1 [1] => 20 ) [1] => Array ( [0] => 2 [1] => 20 ) [2] => Array ( [0] => 1 [1] => 10 ) )
Notice that each array combination has an index preceding it (starting at 0)
The following code demonstrates this:
<?php
session_start();
unset($_SESSION['ingredients']);
$_SESSION['ingredients'][] = array(1, 20);
$_SESSION['ingredients'][] = array(2, 20);
$_SESSION['ingredients'][] = array(1, 10); // adding the same ingredient again
print_r($_SESSION['ingredients']);
?>
Why not use the ingredient id as the key in the session array and then append each value to it as an element
$_SESSION['ingredients'][$_POST['ingredient']][] = $_POST['qty'];
This would give you
Array(
[1] => array(
[0] => 50,
[1] => 50
)
)
Just a thought, I don't know if this would work for your use case
change your inserted array to this:
$_SESSION['ingredients'][count($_SESSION['ingredients'])] = array($_POST['ingredient'],$_POST['qty']);
I use it in my program.
I have an array that I'm simply trying to order by a score key that contains the value that I'm trying to sort by. The desired results would change the order of the array below to display the index in the following order: [0], [2], [1].
I'm looping through the results which are pulled from a database. I'm creating a key named score and then pushing the $row2 array in to a separate array because if I use mysql_data_seek it gets rid of the score key.
Also it's creating an unwanted key score at the bottom.
How can I best clean this up and make sure the results are ordered high to low as desired?
$my_array = array();
while ($row2 = mysql_fetch_assoc($result2))
{
//score determined here
//$row2['score'] = ...more math, variable is numeric, not a string
array_push($array_page,$row2);
}
Current undesired results...
Array
(
[0] => Array
(
[score] => 7
)
[1] => Array
(
[score] => 2
)
[2] => Array
(
[score] => 4
)
[score] =>
)
Desired results...
Array
(
[0] => Array
(
[score] => 7
)
[2] => Array
(
[score] => 4
)
[1] => Array
(
[score] => 2
)
)
function scoreSort($a, $b){
if($a['score'] == $b['score']) return 0;
return $a['score'] > $b['score'] ? -1 : 1;
}
usort(&$myArray, 'scoreSort');
on php>5.3 you can use inline-functoins:
usort(&$myArray, function($a,$b){ /* ... */ });
Hello i have an array in php
Array
(
[0] => red
[1] => blue
[2] => green
[3] => yellow
[4] => purple
[5] => white
)
and i want to sort it using that array
Array
(
[0] =>
[1] => 0
[2] => -1
[3] => -5
[4] => -5
[5] => 9
)
so i want the element with the greatest value on the second array to come first on the first array not its value from the second array but the element it self from the first array to move in the first position on the first array! The second bigger to the second place etc.. elements with the same value don't care me how they will be arranged!
the output i want to get is
Array
(
[0] => white
[1] => blue
[2] => green
[3] => yellow
[4] => purple
[5] => red
)
You can use array_multisort() :
$ar1 = array(/* your SO links */);
$ar2 = array(/* your numbers */);
array_multisort($ar2, SORT_DESC, $ar1);
Documentation here
Use array_multisort.
see http://www.php.net/manual/fr/function.array-multisort.php, follow the "Exemple #1 Trier plusieurs tableaux"
Cordially
Lets call your arrays are $dataArray, and $sortArray respectively
asort($sortArray);
foreach ( $sortArray as $key=>$val ) {
$newArray[] = $dataArray[$key];
}
If you need it reversed, just add in a call to array_reverse() at the end.
I think what the OP wants is to sort the first array by the second array's values.
IE- the second array is the vote count for the first array's web pages.
This could be solved more simply if in the first array you have each element as an array with two elements in it, webpage & vote count
$pages = Array
(
array(
'page' => 'http://stackoverflow.com/questions/640805/open-source-ios-components-reusable-views-controllers-buttons-table-cells-e',
'count' => 0
)
array(
'page' => 'http://stackoverflow.com/questions/3889634/fast-and-lean-pdf-viewer-for-iphone-ipad-ios-tips-and-hints',
'count' => -1
)
// etc for the rest...
)
But since the question asked how to do it in the current data structure:
$sorted_values = asort($pages);
$new_pages = array();
$sorted_keys = array_keys($sorted_values);
foreach($sorted_keys as $page_key)
array_push($new_pages, $pages[$page_key]);