(PHP) Separating Arrays into Multidimensional - php

At present I have an array of data [0] - [574].
What I would like to do is split this down into a multidimensional array in 25 parts i.e. [0] - [22] as below:
Array
(
[0] =>
[0] => abc
...
[22] => xyz
[1] =>
[0] => abc
...
[22] => xyz
...
}
I assume it can be done using a for loop to split it all up - Ive tried a few methods but havent seemed to quite get there yet!
Thanks
-mango

There is a built-in function for that:
$parts = array_chunk($array, 23);

I've just used dummy data, but you'll get the idea:
// Set up input with dummy data
$input = array();
for ($i = 0; $i < 574; $i++) {
$input[] = $i . 'aaa';
}
$out = array();
for ($i = 0, $j = sizeof($input); $i < $j; $i++) {
$bucket = floor($i / ($j / 25));
if (!isset($out[$bucket])) {
$out[$bucket] = array();
}
$out[$bucket][] = $input[$i];
}
print_r($out);

$array = array();
$chunks = ceil(count($array) / 25);
$new = array_chunk($array, $chunks);

Related

Sorting an array of numbers with for-loop

I have a task of sorting an array of numbers in both ascending and descending order. The challenge is, I can't use the built-in sort function, but loop through the array with for-loops instead.
I am a total newbie when it comes to PHP and this task straight off baffles me. Here is the code I'm supposed to work with:
<?php
$arr = $_GET['arr'];
$table = explode(',', $arr);
$count = count($table);
// What I tried to work with, didn't get to work:
for ($i = 0; $i < $count; $i++) {
for ($j = $i + 1; $j < $count; $j++) {
if ($table[$i] > $table[$j]) {
$temp = $table[$i];
$table[$i] = $table[$j];
$table[$j] = $temp;
$asc = implode("," $temp);
}
}
}
echo "Ascending: $asc";
echo "Descending: $desc";
?>
Any clue why this doesn't run? At some point, I got the first (largest) number in the array with the echo, but don't really know what broke that either.
Move the line
$asc = implode(",", $table);
from its current location below the outer for loop and maybe add the line
$desc = implode(",", array_reverse($table));
to get the descending sort order.
Many ways to make it. One solution you will find in the code below. you will certainly notice that the sorting depends only on one operator. Therefore, you can build a function out of it by specifying the sorting as a parameter. function(array $array, string $sort) {}
DESC
$arr= array(112,21,130,140,2,42);
for($i=0; $i<count($arr)-1; $i++)
{
for($j=0; $j<count($arr)-1; $j++)
{
if($arr[$j] < $arr[$j+1]){
$temp= $arr[$j+1];
$arr[$j+1]= $arr[$j];
$arr[$j]= $temp;
}
}
}
print_r($arr);
Output:
Array
(
[0] => 140
[1] => 130
[2] => 112
[3] => 42
[4] => 21
[5] => 2
)
ASC
$arr= array(112,21,130,140,2,42);
for($i=0; $i<count($arr)-1; $i++)
{
for($j=0; $j<count($arr)-1; $j++)
{
if($arr[$j] > $arr[$j+1]){
$temp= $arr[$j+1];
$arr[$j+1]= $arr[$j];
$arr[$j]= $temp;
}
}
}
print_r($arr);
Output
Array
(
[0] => 2
[1] => 21
[2] => 42
[3] => 112
[4] => 130
[5] => 140
)

How to get the factorial value of each number in an array?

I am trying to get an factorial value of each item in array by using this method but this outputs only one value
can any body help me finding where i am doing wrong?
function mathh($arr, $fn){
for($i = 1; $i < sizeof($arr); $i++){
$arr2 = [];
$arr2[$i] = $fn($arr[$i]);
}
return $arr2;
}
$userDefined = function($value){
$x = 1;
return $x = $value * $x;
};
$arr = [1,2,3,4,5];
$newArray = mathh($arr, $userDefined);
print_r($newArray);
You're going to need a little recursion so in order to do that you need to pass the lambda function into itself by reference:
function mathh($arr, $fn){
$arr2 = []; // moved the array formation out of the for loop so it doesn't get overwritten
for($i = 0; $i < sizeof($arr); $i++){ // starting $i at 0
$arr2[$i] = $fn($arr[$i]);
}
return $arr2;
}
$userDefined = function($value) use (&$userDefined){ // note the reference to the lambda function $userDefined
if(1 == $value) {
return 1;
} else {
return $value * $userDefined($value - 1); // here is the recursion which performs the factorial math
}
};
$arr = [1,2,3,4,5];
$newArray = mathh($arr, $userDefined);
print_r($newArray);
The output:
Array
(
[0] => 1
[1] => 2
[2] => 6
[3] => 24
[4] => 120
)
I wanted to expand on this some since you're essentially (in this case) creating an array map. This could be handy if you're doing additional calculations in your function mathh() but if all you want to do is use the lambda function to create a new array with a range you could do this (utilizing the same lambda we've already created):
$mapped_to_lambda = array_map($userDefined, range(1, 5));
print_r($mapped_to_lambda);
You will get the same output, because the range (1,5) of the mapped array is the same as your original array:
Array
(
[0] => 1
[1] => 2
[2] => 6
[3] => 24
[4] => 120
)

How to reverse PHP array in partitions

I have a simple array that looks like this:
Array (
[0] => Array (
[id] => 8692
[name] => d
)
[1] => Array (
[id] => 8691
[name] => c
)
[2] => Array (
[id] => 8690
[name] => b
)
[3] => Array (
[id] => 8689
[name] => a
)
[4] => Array (
[id] => 8500
[name] => d
)
[5] => Array (
[id] => 8499
[name] => c
)
[6] => Array (
[id] => 8498
[name] => b
)
[7] => Array (
[id] => 8497
[name] => a
)
)
This array is quite long so I only included the first 4 items to give you an idea.
My problem is that I need the array to be in a format of
a,b,c,d,a,b,c,d
At the moment the format is like:
d,c,b,a,d,c,b,a
By this I mean the ['name'] value which is either a,b,c or d.
So I every 4 items in the array need to be reversed.
I have tried to achieve this but fail every time ending up with lots of for & while loops.
You can do it using array_chunk, array_merge and array_reverse:
$finalArray = array();
$arrays = array_chunk($myArray, 4);
foreach ($arrays as $array) {
$finalArray = array_merge($finalArray, array_reverse($array));
}
All the answers here, while perfectly valid, are pretty much on the order of O(n^2). So I figured I'd give you an O(n / 2), time complexity, solution as an alternative just in case you care about performance. The solution also uses only O(n + n + k) space complexity (in place swap).
Since the requirement is to reverse order of values, I'm ignoring keys and basing the solution on the constraint that the array is always 0-indexed.
To solve this problem, we can generalize the solution as a simple array reverse, which requires a simple O(n/2) operation with in-place swap. We can achieve this simply with two counters, $i starting from the beginning of the array, and $j starting at the end of the array. Thus, we can swap the values at $arr[$i] with that at $arr[$j] and then increment $i and decrement $j, at each step.
function reverseArray(Array $arr) {
for($i = 0, $j = count($arr); $i < $j; $i++, $j--) {
$tmp = $arr[$j];
$arr[$j] = $arr[$i];
$arr[$i] = $tmp;
}
return $arr;
}
Now, to apply the more specific solution of only reverse every group of 4 elements in the array, we just break up the array in partitions of 4 values, and only reverse each of those partitions at a time. Which just expands on the example above of reverseArray() by altering the starting and ending positions of the $i and $j counter to only reverse within each partition.
Thus we arrive the O(n / 2) solution here by just adding another loop for the partition size, and keep the inner loop from the earlier example.
function reverseArrayPartition(Array $arr, $partitionSize = 4) {
$end = count($arr);
// reverse only one partition at a time
for($start = 0; $start < $end; $start += $partitionSize ) {
$from = $start;
$to = $start + $partitionSize - 1;
for($i = $from, $j = $to; $i < $j; $i++, $j--) {
// swap the transposing values
$tmp = $arr[$j];
$arr[$j] = $arr[$i];
$arr[$i] = $tmp;
}
}
return $arr;
}
$arr = [4,3,2,1,4,3,2,1];
var_dump(reverseArrayPartition($arr)); // expected [1,2,3,4,1,2,3,4]
This will work with any array size at any $partitionSize so it's efficient if you're trying to do this on very large arrays.
You can iterate the array with a for and increment with 4 each time and keep the current offset in other variable and use array_slice to get the current slice of array and reverse order using array_reverse
I am thinking of something like this:
$step = 4;
$offset = 0;
$new_arr = []; //Here we create the new array.
for($i=0; $i<count($arr); $i+=$step) {
$part_of_array = array_slice($arr, $offset, $step);
$part_reverse = array_reverse($part_of_array);
$new_arr = array_merge($new_arr, $part_reverse);
$offset += $step;
}
print_r($new_arr); //Here will be the array as you expected.
All the content in the for can be simplify to:
$new_arr = array_merge($new_arr, array_reverse(array_slice($arr, $offset, $step)));
$offset += $step;
Not harcoding every 4, reverse based on char code of name value
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
/**
*/
$in = [
['name'=>'d','id'=>1]
, ['name'=>'c','id'=>12]
, ['name'=>'b','id'=>13]
, ['name'=>'a','id'=>14]
, ['name'=>'d','id'=>15]
, ['name'=>'c','id'=>16]
, ['name'=>'b','id'=>17]
, ['name'=>'a','id'=>18]
];
$last = PHP_INT_MAX;
$toReverse = [];
$out = [];
foreach ($in as $value) {
$p = ord($value['name']);
if ( $p < $last ) {
//echo 'ToReverse',var_export($value,true),"\n";
$toReverse[] = $value;
}
else {
$out = array_merge($out,array_reverse($toReverse));
//echo 'Join',var_export($out,true),"\n";
$toReverse = [$value];
}
$last = $p;
}
$out = array_merge($out,array_reverse($toReverse));
print_r($out);

Turning array values back into variables

I have made an array of userid's that prints out like this
Array ( [0] => 8,7 [1] => 8,6 [2] => 6 [3] =>8,7 [4] =>6,8 [5] => 6,9).
I'm trying to figure out how to turn these values within the array back into a variable that I can use like $userid. So for example turn [4] =>6,8 into $userid =6 and $userid=8.
$ids = array( [0] => 8,7 [1] => 8,6 [2] => 6 [3] =>8,7 [4] =>6,8 [5] => 6,9);
$explode_ids = explode(',', $ids[0]);
$id1 = $explode_ids[0];
$id2 = $explode_ids[1];
If you want this for every value of the array in loop:
for($i=0; $i<=5; $i++) {
$explode_ids = explode(',', $ids[$i]);
$id1 = $explode_ids[0];
$id2 = $explode_ids[1];
}
Do u want sth like that?
$array_with_ids = [];
$len = count($array);
for ($a = 0; $a < $len; $a++)
{
$array2 = explode(',', $array[$a]);
$len2 = count($array2);
for ($b = 0; $b < $len2; $b++)
{
$array_with_ids[] = $array2[$b];
}
}
And, finally, u have all ids in $array_with_ids array, so u can call them by $array_with_ids[0], $array_with_ids[1]...

PHP Function for Comparing Elements in Different Arrays

I have two arrays like so (however there can be more or less than 2 (any amount)):
[0] => Array
(
[assessedUsers] => Array
(
[0] => Array
(
[scores] => Array
(
[0] => 10
[1] => 10
[2] => 10
[3] => 10
)
)
[1] => Array
(
[scores] => Array
(
[0] => 9
[1] => 10
[2] => 0
[3] => 9
)
)
)
)
Where the length of the scores array is always the same in both arrays.
I would like to take each element from each array, one by one, and average them, then append them into a new array.
For example, the output of my desired function would look like this:
[1] => Array
(
[scores] => Array
(
[0] => 9.5
[1] => 10
[2] => 5
[3] => 9.5
)
)
Is there a function that can do this, or do I need a couple nested for() loops? If I need to use forl loops how would I go about doing it? I'm a little confused on the logic behind it.
Currently what I have is:
for ($i = 0; $i < sizeof($data["assessedUsers"]); $i++) {
for ($j = 0; $j < sizeof($data["assessedUsers"][$i]["scores"]); $j++) {
}
}
and I'm a little confused as to what to where to go next. Thanks in advance!
$mean = array_map( function($a, $b) { return ($a + $b) / 2; },
$data['assessedUsers'][0]['scores'],
$data['assessedUsers'][1]['scores']
);
var_dump($mean);
And append $mean anywhere you want. Or do you have more than 2 arrays? You did not state it in your question.
ps: for any number of subarrays
$arr = array(
array('scores' => array(10,10,10,10)),
array('scores' => array(9,10,0,9)),
array('scores' => array(1,2,3,4))
);
// remove arrays from the key
$tmp = call_user_func_array( function() { return func_get_args(); },
array_map( function($a) { return $a['scores']; }, $arr)
);
// add arrays by each element
$mean = array_map( function($val, $ind) use($tmp) {
$sum = 0;
foreach($tmp as $i => $t)
$sum += $t[$ind];
return $sum / ($i + 1);
}, $tmp[0], array_keys($tmp[0]));
var_dump($mean);
Probably two loops:
$newarray();
foreach($main_array as $user) {
foreach($user['assessedUser'][0]['scores'] as $score_key => $user0_value) {
$user1_value = $user['assessedUser'][1]['scores'][$score_key];
$average = ($user1_value + $user0_value) / 2;
... stuff into new array
}
}
I have solution for you, hope this help :)
$scores = array();
for ($i = 0; $i < sizeof($data["assessedUsers"]); $i++) {
for ($j = 0; $j < sizeof($data["assessedUsers"][$i]["scores"]); $j++) {
if(isset($scores[$j])){
$scores[$j] = ($scores[$j] + $data["assessedUsers"][$i]["scores"][$j]) / ($i +1);
}else{
$scores[] = $data["assessedUsers"][$i]["scores"][$j];
}
}
}
$scores[] = $scores;
view Example :)
http://codepad.org/upPjMEym

Categories