Related
I have an array which as dynamic nested indexes in e.g. I am just using 2 nested indexes.
Array
(
[0] => Array
(
[0] => 41373
[1] => 41371
[2] => 41369
[3] => 41370
)
[1] => Array
(
[0] => 41378
[1] => 41377
[2] => 41376
[3] => 41375
)
)
Now I want to create a single array like below. This will have 1st index of first array then 1st index of 2nd array, 2nd index of first array then 2nd index of 2nd array, and so on. See below
array(
[0] =>41373
[1] => 41378
[2] => 41371
[3] => 41377
[4] => 41369
[5] => 41376
[6] => 41370
[7] => 41375
)
You can do something like this:
$results = [];
$array = [[1,2,3,4], [1,2,3,4], [1,2,3,4]];
$count = 1;
$size = count($array)-1;
foreach ($array[0] as $key => $value)
{
$results[] = $value;
while($count <= $size)
{
$results[] = $array[$count][$key];
$count++;
}
$count = 1;
}
I think you need something like this:
function dd(array $arrays): array
{
$bufferArray = [];
foreach($arrays as $array) {
$bufferArray = array_merge_recursive($bufferArray, $array);
}
return $bufferArray;
}
$array1 = ['41373','41371','41369','41370'];
$array2 = ['41378','41377', '41376', '41375'];
$return = array();
$count = count($array1)+count($array2);
for($i=0;$i<($count);$i++){
if($i%2==1){
array_push($return, array_shift($array1));
}
else {
array_push($return, array_shift($array2));
}
}
print_r($return);
first count the arrays in the given array, then count the elements in the first array, than loop over that. All arrays should have the same length, or the first one should be the longest.
$laArray = [
['41373','41371','41369','41370'],
['41378', '41377', '41376', '41375'],
['43378', '43377', '43376', '43375'],
];
$lnNested = count($laArray);
$lnElements = count($laArray[0]);
$laResult = [];
for($lnOuter = 0;$lnOuter < $lnElements; $lnOuter++) {
for($lnInner = 0; $lnInner < $lnNested; $lnInner++) {
if(isset($laArray[$lnInner][$lnOuter])) {
$laResult[] = $laArray[$lnInner][$lnOuter];
}
}
}
this would be the simplest solution:
$firstarr = ['41373','41371','41369','41370'];
$secondarr = ['41378','41377','41376','41375'];
$allcounged = count($firstarr)+count($secondarr);
$dividedintotwo = $allcounged/2;
$i = 0;
while ($i<$dividedintotwo) {
echo $firstarr[$i]."<br>";
echo $secondarr[$i]."<br>";
$i++;
}
i have two arrays
$value_array = array('50','40','30','20','10');
$customer = array('300','200','100');
i want to distribute the value array to customers based on the value of customers that is taken as limit.adding values by checking it wont cross the limit that is 300 , 200 and 100.
but customer array not working one direction it should work first forward and then backward like that
i want to produce an array in form of
Array
(
[0] => Array
(
[0] => 50
)
[1] => Array
(
[0] => 40
[1] => 10
)
[2] => Array
(
[0] => 30
[1] => 20
)
)
After completing customer loop first time it should start from last to first. both array count will change , i mean count.
value array should check 50 -> 300 , 40->200, 30->100 then from last ie, 20 ->100, 10->200 etc.
I tried like
$i = 0;
while($i < count($customer)){
foreach($value_array as $k=>$value){
$v = 0;
if($value <= $customer[$i]){
$customer2[$i][] = $value;
unset($value_array[$k]);
$v = 1;
}
if($v ==1){
break;
}
}
//echo $i."<br/>";
if($i == (count($customer)-1) && (!empty($value_array))){
$i = 0;
$customer = array_reverse($customer, true);
}
$i++;
}
echo "<pre>";
print_r($customer2);
$valueArray = array('50','40','30','20','10','0','-11');
$customer = array('300','200','100');
function parse(array $valueArr, array $customerArr)
{
$customerCount = count($customerArr);
$chunkedValueArr = array_chunk($valueArr, $customerCount);
$temp = array_fill(0, $customerCount, array());
$i = 0;
foreach ($chunkedValueArr as $item) {
foreach ($item as $key => $value) {
$temp[$key][] = $value;
}
$temp = rotateArray($temp);
$i++;
}
// if $i is odd
if ($i & 1) {
$temp = rotateArray($temp);
}
return $temp;
}
function rotateArray(array $arr)
{
$rotatedArr = array();
//set the pointer to the last element and add it to the second array
array_push($rotatedArr, end($arr));
//while we have items, get the previous item and add it to the second array
for($i=0; $i<sizeof($arr)-1; $i++){
array_push($rotatedArr, prev($arr));
}
return $rotatedArr;
}
print_r(parse($valueArray, $customer));
returns:
Array
(
[0] => Array
(
[0] => 50
[1] => 0
[2] => -11
)
[1] => Array
(
[0] => 40
[1] => 10
)
[2] => Array
(
[0] => 30
[1] => 20
)
)
Im making a tree to store words and an associated number array in php. I need it to look something like this:
Words: apple, ant
[a] => Array
(
[p] => Array
(
[p] => Array
(
[l] => Array
(
[e] => Array
(
[0] => Array
(
[0] => 0
[1] => 0
[2] => 1
[3] => 2
[4] => 3
[5] => 4
)
)
)
)
)
[n] => Array
(
[t] => Array
(
[0] => Array
(
[0] => 0
[1] => 1
[2] => 2
[3] => 0
[4] => 0
[5] => 4
)
)
)
)
Of course apple and ant need to share the same [a] index. Im close, but I cant figure out how to properly keep track of the tree index so 'apple' gets into the tree fine but 'ant' is inserted as 'nt'. Heres my code at the moment:
private function insertWordsIntoTree()
{
foreach ($this->words as $word)
{
$characters = preg_replace('/[0-9]+/', '', $words);
$points = $this->getPoints($word);
$this->tree = $this->buildTree($characters, $points, $this->tree);
}
print_r($this->tree);
}
private function buildTree($characters, array $points, array $tree)
{
for ($i = 0; $i < strlen($characters); $i++)
{
$character = $characters[$i];
$remaining_characters = substr($characters, $i + 1);
if (strlen($characters) === 1)
{
$child = [];
$child[$character] = [$points];
return $child;
}
elseif (!isset($tree[$character]))
{
$tree[$character] = $this->buildTree($remaining_characters, $points, []);;
break;
}
else
{
$this->buildTree($remaining_characters, $points, $tree[$character]);
}
}
return $tree;
}
Im pretty sure the problem is at the else statement...I dont think Im keeping track of the current tree index properly. Any help would be much appreciated.
Here's a simple approach that passes the recursion off to php:
$tree = array();
foreach($words as $word) {
$characters = array_reverse(str_split($word));
$temp = array();
foreach($characters as $index => $character) {
if($index == 0) {
$temp[] = getPoints($word);
}
$temp = array(
$character => $temp
);
}
$tree = array_merge_recursive($tree, $temp);
}
After one week searching and converting many algorithm from other language into php to make an array that contain "combination k from n". I'm stuck.
please help me.
This is my code (using php):
function comb($item,$arr,$out, $start, $n, $k, $maxk) {
if ($k > $maxk) {
foreach($arr as $ar){
echo "$ar";
echo "<br/>";
}
return;
}
for ($i=$start; $i<=$n; $i++) {
$arr[$k] = $item[$i-1];
comb($isi, $arr, $out, $i+1, $n, $k+1, $maxk);
}
}
$team = array("A","B","C","D");
$ar = array();
$o = array();
comb($team,$ar,$o,1,4,1,2);
Recursive algorithm above is really confuse me. The code above was successful to form the combination but I cannot merge them into one array because of its recursive characteristics. I just want to make an array that contain the result of combination of 2 from 4 items. Like this (see below)
Array (
[0] => Array (
[1] => A
[2] => B
)
[1] => Array (
[1] => A
[2] => C
)
[2] => Array (
[1] => A
[2] => D
)
[3] => Array (
[1] => B
[2] => C
)
[4] => Array (
[1] => B
[2] => D
)
[5] => Array (
[1] => C
[2] => D
)
)
I know I still far from the answer. But please guide me, to reach that answer. Perhaps you know the other technique, it doesn't matter. If your code works, I will use it. No matter what the technique you've used. Any ideas would be gratefully appreciated,Thank you..!
An (I think) simpler recursive implementation is:
<?php
/* Given the array $A, returns the array of $k-subsets
of $A in lexicographical order. */
function k_lex_subset($A,$k) {
if (($k <= 0) or (count($A) < $k)) { return array(); }
else if ($k <= 1) { return array_chunk($A,1); }
else {
$v = array_shift($A);
$AwA = k_lex_subset($A,$k-1);
foreach($AwA as &$vp) {
array_unshift($vp,$v);
}
$AwoA = k_lex_subset($A,$k);
$resultArrs = array_merge($AwA, $AwoA);
return($resultArrs);
}
}
$team = array("A","B","C","D");
print_r(k_lex_subset($team,2));
?>
which returns
Array
(
[0] => Array
(
[0] => A
[1] => B
)
[1] => Array
(
[0] => A
[1] => C
)
[2] => Array
(
[0] => A
[1] => D
)
[3] => Array
(
[0] => B
[1] => C
)
[4] => Array
(
[0] => B
[1] => D
)
[5] => Array
(
[0] => C
[1] => D
)
)
and will work for any size array, and any $k.
The term you are looking for is (lexicographical) k-subset enumeration where $k is 2 in this specific case.
Explanation
The idea is very simple. Assume we have (for example) a set {A,B,C,D}. We want to start with all sets with A in, and so we consider subsets of size 1-less coming from {B,C,D} and append A to them yielding
{{A,B}, {A,C}, {A,D}}
and then we consider all subsets of size 2 without A in
{{B,C}, {B,D}, {C,D}}
and then we just merge the two. It is hopefully easy to see how, in general, this yields a nice recursive strategy for constructing the k-subsets of a set (instead of just k=2).
Reference
A fantastic reference on this sort of thing is Vol 4 Fasicle 3 of Knuth's The Art of Computing Programming.
This should do the trick to reach the array you've described above:
<?php
$array = array("A","B","C","D");
function transformArray( $array ) {
$returnArray = array();
for( $i=0; $i < count($array); $i++ ) {
for( $j=$i+1; $j < count($array); $j++ ) {
$returnArray[] = array( $array[$i], $array[$j] );
}
}
return $returnArray;
}
print_r(transformArray($array));
?>
Not exactly sure on the necessity of start, n, and k, but this should get you the expected output. If you provide some more details on why those counters would be necessary, we can get you a more thorough answer.
function comb($itemArray, $start, $n, $k, $maxk) {
//if ($k > $maxk) return;
$outputArray = array();
foreach($itemArray AS $index => $firstChar) {
for($i = $index+1; $i<count($itemArray); $i++) {
$secondChar = $itemArray[$i];
$outputArray[] = array($firstChar, $secondChar);
}
}
return $outputArray;
}
$teamArray = array("A","B","C","D");
$resultArray = comb($teamArray,1,4,1,2);
ppr($resultArray);
function ppr($variable) {
echo '<pre>';
print_r($variable);
echo '</pre>';
}
function comb($a, $len){
if ($len > count($a))return array();
$out = array();
if ($len==1) {
foreach ($a as $v) $out[] = array($v);
return $out;
}
$len--;
while (count($a) > $len) {
$b = array_shift($a);
$c = comb($a, $len);
foreach ($c as $v){
array_unshift($v, $b);
$out[] = $v;
}
}
return $out;
}
$test = array('a','b','c','d');
$a = comb($test,2);
print_r($a);
would give you:
Array(
[0] => Array
(
[0] => a
[1] => b
)
[1] => Array
(
[0] => a
[1] => c
)
[2] => Array
(
[0] => a
[1] => d
)
[3] => Array
(
[0] => b
[1] => c
)
[4] => Array
(
[0] => b
[1] => d
)
[5] => Array
(
[0] => c
[1] => d
)
)
Why are you doing
echo "ar"
instead of
echo $ar
Also are you looking for permutation or combination? Here is a site with very nice algorithms for both. The implementation is in java but it's very clear. so converting to php won't be difficult: http://geekviewpoint.com/Numbers_functions_in_java/
If you want a pure clean recursive way use this:
function comb($item, $n) {
return comb_rec($item, array(), $n);
}
function comb_rec($items, $c, $n) {
if (count($c) == $n) {
return array($c);
}else{
if (count($items) == 0) {
return $items;
}else{
$list = $items;
$head = array_shift($list);
$tail = $list;
$current = $c;
array_push($current,$head);
return array_merge(comb_rec($tail, $current, $n),comb_rec($tail, $c, $n));
}
}
}
$team = array("A","B","C","D");
$all = comb($team,2);
print_r($all);
It should quite simple algorithm, but I just can't get around it.
I have some arrays in alphabetical order
[0] => Array
(
[0] => a
[1] => b
[2] => c
)
and for example
[0] => Array
(
[0] => a
[1] => b
[2] => c
[3] => d
)
and I need to sort them into rows. For example:
I should receive a table with 3 columns and as many rows as it may get and it should be in alphabetical order.
Here is an example:
First array should be converted into
[0] => Array
(
[0] => Array
(
[0] => a
[1] => b
[2] => c
)
)
But second one should be as
[1] => Array
(
[0] => Array
(
[0] => a
[1] => c
[2] => d
)
[1] => Array
(
[0] => b
)
)
I'm writing it in php, so if anyone can help I would be really appreciated.
UPD:
Code example:
function sortAsOrdered( array $categories )
{
foreach ( $categories as $groupId => $group )
{
$regroupMenuItems = array();
$limit = count( $group );
$rows = ceil( $limit / 3 );
for ( $i = 0; $i < $rows; ++$i )
{
$jumper = 0;
for ( $j = 0; $j < 3; $j++ )
{
if ( 0 == $jumper )
{
$jumper = $i;
}
if ( isset( $group[ $jumper ] ) )
{
$regroupMenuItems[ $i ][ $j ] = $group[ $jumper ];
}
$jumper = $jumper + $rows;
}
}
$categories[ $groupId ] = $regroupMenuItems;
}
return $categories;
}
Guys I solved this one. Here you could see my algorithm http://pastebin.com/xe2yjhYW.
But don't be sad your help will not go in vain. I probably will place bounty just for those who helped with this dificult algorithm for me.
Guys thanks one more time. Your thoughts inspired me to think differently.
array_chunk() wold have been the solution but as you want it to be specially sorted, that wouldn't help you much.
So here is my five cents:
function array_chunk_vertical($input, $size_max) {
$chunks = array();
$chunk_count = ceil(count($input) / $size_max);
$chunk_index = 0;
foreach ($input as $key => $value) {
$chunks[$chunk_index][$key] = $value;
if (++$chunk_index == $chunk_count) {
$chunk_index = 0;
}
}
return $chunks;
}
$array = array('a', 'b', 'c', 'd', 'e', 'f');
var_dump(array_chunk_vertical($array, 2));
Which will give you:
array
0 =>
array
0 => string 'a' (length=1)
3 => string 'd' (length=1)
1 =>
array
1 => string 'b' (length=1)
4 => string 'e' (length=1)
2 =>
array
2 => string 'c' (length=1)
5 => string 'f' (length=1)
The downside of this function is that you can only tell the max number of elements in a chunk, and then it equally divides the array to chunks. So for [4] and max_size 3 you will get [2,2] unlike the expected [3,1].
<?php
$five_el = array('a', 'b', 'c', 'd', 'e');
$two_el = array('a', 'b');
$three_el = array('a', 'b', 'c');
$six_el = array('a', 'b', 'c', 'd', 'e', 'f');
function multid($sorted_array) {
$mulidarray = array();
$row = 0;
$column = 0;
foreach ($sorted_array as $value) {
if ($column == 3) {
$row++;
}
$column++;
if (!isset($mulidarray[$row])) {
$mulidarray[$row] = array();
}
$multidarray[$row][] = $value;
}
return $multidarray;
}
var_dump(multid($five_el));
var_dump(multid($two_el));
var_dump(multid($three_el));
var_dump(multid($six_el));
array_chunk is a natural first approach to the problem, but it won't do exactly what you need to. If the solution is provided that way, you need to either restructure the resulting array or restructure the input before processing it, as below:
$input = range('a', 'k'); // arbitrary
$columns = 3; // configure this
$rows = ceil(count($input) / $columns);
// fugly, but this way it works without declaring a function
// and also in PHP < 5.3 (on 5.3 you'd use a lambda instead)
$order = create_function('$i',
'$row = (int)($i / '.$rows.');'.
'$col = $i % '.$rows.';'.
'return $col * ('.$columns.' + 1) + $row;');
// $order is designed to get the index of an item in the original array,
// and produce the index that item would have if the items appeared in
// column-major order instead of row-major as they appear now
$array = array_map($order, array_keys($input));
// replace the old keys with the new ones
$array = array_combine($array, $input);
// sort based on the new keys; this will effectively transpose the matrix,
// if it were already structured as a matrix instead of a single-dimensional array
ksort($array);
// done!
$array = array_chunk($array, $columns);
print_r($array);
See it in action.
Let's see if this is nearer the mark
function splitVerticalArrayIntoColumns($aInput, $iNumberOfColumns) {
//output array
$aOutput = array();
//the total length of the input array
$iInputLength = count($aInput);
//the number of rows will be ceil($iInputLength / $iNumberOfColumns)
$iNumRows = ceil($iInputLength / $iNumberOfColumns);
for($iInputIndex = 0; $iInputIndex < $iInputLength; $iInputIndex++) {
$iCurrentRow = $iInputIndex % $iNumRows;
$aOutput[$iCurrentRow][] = $aInput[$iInputIndex];
}
//return
return $aOutput;
}
Which - when run thus:
$aList = array("a", "e", "d", "b", "c");
echo 'array("a", "e", "d", "b", "c")' . "\n\n";
print_r(splitVerticalArrayIntoColumns($aList, 3));
Gives:
array("a", "e", "d", "b", "c")
Array
(
[0] => Array
(
[0] => a
[1] => d
[2] => c
)
[1] => Array
(
[0] => e
[1] => b
)
)
That's not sorting each row yet but is that the kind of thing you're after?
begin facepalm edit
... or of course, array_chunk($aList, 3) after you've sorted it O_o
http://uk3.php.net/manual/en/function.array-chunk.php
I'll leave everything below for reference or whatever - I'd completely forgotten about array_chunk()
end facepalm edit
I'd use a modulo in a loop where you're counting the array index (after sorting the array) - for instance if you're trying to split an array into 3 "columns" you could try something like:
if($iIndex % 3 == 0) {
//... create a new array
}
else {
//... add to an existing array
}
EDIT code example:
$aList = array("a", "e", "d", "b", "c");
sort($aList);
$iDesiredNumberOfColumns = 3;
$iListLength = count($aList);
$aListInColumns = array();
$iRowNumber = 0;
for($iIndex = 0; $iIndex < $iListLength; $iIndex++) {
$iColumnNumber = $iIndex % 3;
if($iIndex != 0 && $iColumnNumber == 0) {
$iRowNumber++;
}
$aListInColumns[$iRowNumber][$iColumnNumber] = $aList[$iIndex];
}
Just ran it on my local server (and corrected the typo), and it outputs as:
Array
(
[0] => Array
(
[0] => a
[1] => b
[2] => c
)
[1] => Array
(
[0] => d
[1] => e
)
)
There's probably a tidier way of doing it (that's a little procedural) but it should do the job.
How about:
$arrs = array(
array('a','b','c'),
array('a','b','c','d'),
array('a','b','c','d','e'),
array('a','b','c','d','e','f'),
array('a','b','c','d','e','f','g')
);
$nbcols = 3;
foreach ($arrs as $arr) {
$arr_size = count($arr);
$nblines = ceil($arr_size/$nbcols);
$res = array();
$l = 0;
foreach ($arr as $el) {
if ($l == $arr_size - 1 && count($res[0]) < $nbcols) $l=0;
$res[$l%$nblines][] = $el;
$l++;
}
print_r($res);
}
output:
Array
(
[0] => Array
(
[0] => a
[1] => b
[2] => c
)
)
Array
(
[0] => Array
(
[0] => a
[1] => c
[2] => d
)
[1] => Array
(
[0] => b
)
)
Array
(
[0] => Array
(
[0] => a
[1] => c
[2] => e
)
[1] => Array
(
[0] => b
[1] => d
)
)
Array
(
[0] => Array
(
[0] => a
[1] => c
[2] => e
)
[1] => Array
(
[0] => b
[1] => d
[2] => f
)
)
Array
(
[0] => Array
(
[0] => a
[1] => d
[2] => g
)
[1] => Array
(
[0] => b
[1] => e
)
[2] => Array
(
[0] => c
[1] => f
)
)
In order to do this, you need to do two operations:
First, split the array into 3 groups, as evenly as possible.
function array_grouped($arr, $group_count)
{
if (!count($arr)) return array();
$result = array();
for ($i = $group_count; $i > 0; --$i)
{
# break off the next ceil(remaining count / remaining columns) elements
# (avoiding FP math, cause that way lies madness)
$result[] = array_splice($arr, 0, ((count($arr)-1) / $i) + 1);
}
return $result;
}
Then, "transpose" the array, so that rows and columns switch places.
function array_transposed($arr)
{
$result = array();
foreach ($arr as $x => $subarr)
{
foreach ($subarr as $y => $val)
{
if (!isset($result[$y])) $result[$y] = array();
$result[$y][$x] = $val;
}
}
return $result;
}
array_transposed(array_grouped($arr, 3)) gives you entries in the order you want them.
YAYAYAY!! I've got it. You could turn this into a function if you'll be doing it regularly.
# Here we setup our array and the number of columns we want.
$myArray = range('a','d');
$numCols = 3;
# Here we break ourselves up into columns
for ($i = 0; $i < $numCols; $i++) {
$numRows = ceil(count($myArray) / ($numCols - $i));
$columns[$i] = array_slice($myArray,0,$numRows);
$myArray = array_slice($myArray,$numRows);
}
# Here we transpose our array to be in rows instead of columns.
for ($i = 0; $i < $numCols; $i++) {
for ($j = 0; $j < count($columns[$i]); $j++) {
$rows[$j][$i] = $columns[$i][$j];
}
}
# Our rows are now in $rows
var_dump($rows);
The output from this is:
array(2) {
[0]=>
array(3) {
[0]=>
string(1) "a"
[1]=>
string(1) "c"
[2]=>
string(1) "d"
}
[1]=>
array(1) {
[0]=>
string(1) "b"
}
}
If to say it shortly, then here is a method for that algorithm.
/**
* #param array $toTransform
* #param int $columnsMax
* #return array
*/
private function transformation( array $toTransform, $columnsMax = 3 )
{
// First divide array as you need
$listlen = count( $toTransform );
$partlen = floor( $listlen / $columnsMax );
$partrem = $listlen % $columnsMax;
$partition = array();
$mark = 0;
for ( $px = 0; $px < $columnsMax; $px++ )
{
$incr = ( $px < $partrem ) ? $partlen + 1 : $partlen;
$partition[ $px ] = array_slice( $toTransform, $mark, $incr );
$mark += $incr;
}
// Secondly fill empty slots for easy template use
$result = array();
for ( $i = 0; $i < count( $partition[0] ); $i++ )
{
$tmp = array();
foreach ( $partition as $column )
{
if ( isset( $column[ $i ] ) )
{
$tmp[] = $column[ $i ];
}
else
{
$tmp[] = '';
}
}
$result[] = $tmp;
}
return $result;
}
Also I included PHPUnit test for that. You can find it at, that link.