How can you convert the following code to PHP?
summat = [sum(arra[i:i+4]) for i in range(0,len(arra),4)]
My attempt
$summat = array()
foreach ( range(0, $arra.length, 4) as $i) {
$summat = array ( array_sum( array_slice( $array, $i, $i+5) ) ) // don't know how to append the sums the array
$sum = array();
foreach(range(0, count($a), 4) as $i)
$sum []= array_sum(array_slice($a, $i, 4));
"[]=" is an append-to-array operator
slice's second parameter is slice length, not the last index
or even simpler
$sum = array_map('array_sum', array_chunk($a, 4));
To append a value to an array, use:
$summat[] = array_sum(...);
The PHP way of doing ranges is similar to the C way:
for($i = 0; $i < count($arra); $i += 4) {
// ...
}
Related
I have two arrays which I want to multiply and get the final sum. First one is fixed but the second one could have missing elements. For example:
$array1 = array(1, 2, 3, 4, 5);
$array2 = array(1, 3, 5);
Lets say I've got missing elements $array2[1] and $array2[3]. I want to be able to multiply and sum up the rest as:
$sum = array_sum($array1[0] * $array2[0] + $array1[1] * $array2[1] + $array1[2] * $array2[2] + $array1[3] * $array2[3] + $array1[4] + $array2[5]);
Length of arrays may also vary so can't do it the way I've written it above. Any suggestions?
You can complete the array2 missing values as 1, then make the two array have the same length.
$missingKeys = [1,3];
foreach($missingKeys as $k)
{
$array2[$k] = 1;
}
$sum = 0;
foreach($array1 as $k => $v)
{
$sum += $v * $array1[$k];
}
Ok, I didn't use my own advise, but I think this might work?
$total = 0;
foreach ($array1 as $index => $value)
{
if (isset($array2[$index])) $total += $value*$array2[$index];
else $total += $value;
}
echo $total;
The assumption is that all elements of $array2 are present in $array1, but not necessarily the other way around.
As you wrote in your question that the first array is leading (has all the indexes) you only need to iterate over it and eventually multiply with the value from the second array or one:
$sum = 0;
foreach ($array1 as $k => $v) {
$sum += $v * ($array2[$k] ?? 1);
}
Different to the accepted answer, there is no need to manipulate the second array.
If I understood your question properly, and your looking for array multiplication, you could use 2 for loops, iterating one of them and multiplying. Your probably looking for something like this:
for ($i = 0; $i < count($array1); $i++) {
for ($j = 0; $j < count($array2); $j++) {
$sum += $array1[$i] * $array2[$j];
}
}
Why is 0 returned from array_rand()? How can I filter out 0? I just want to get 1-20.
$range = range(1, 20);
$total = array();
for($i = 0; $i < 100; $i++){
shuffle($range);
array_push($total, array_rand($range, 3));
}
array_rand() returns the key(s) from the array, and range() built an array with a starting key of 0. Try:
$range = array_combine($range = range(1, 20), $range);
Or to treat the keys as the values and not use the actual values:
$range = array_flip(range(1, 20));
However, you have already shuffled the array so no need for array_rand(), just slice 3 from the beginning:
$range = range(1, 20);
for($i = 0; $i < 100; $i++){
shuffle($range);
$total[] = array_slice($range, 0, 3);
}
Given the following array:
$arr = array(0,0,1,2,2,5,6,7,7,9,10,10);
And assuming $n = 2, what is the most efficient way to get a count of each value in the array within $n of each value?
For example, 6 has 3 other values within $n: 5,7,7.
Ultimately I'd like a corresponding array with simply the counts within $n, like so:
// 0,0,1,2,2,5,6,7,7,9,10,10 // $arr, so you can see it lined up
$count_arr = array(4,4,4,4,4,3,3,4,4,4, 2, 2);
Is a simple foreach loop the way to go? CodePad Link
$arr = array(0,0,1,2,2,5,6,7,7,9,10,10);
$n = 2;
$count_arr = array();
foreach ($arr as $v) {
$range = range(($v-$n),($v+$n)); // simple range between lower and upper bound
$count = count(array_intersect($arr,$range)); // count intersect array
$count_arr[] = $count-1; // subtract 1 so you don't count itself
}
print_r($arr);
print_r($count_arr);
My last answer was written without fully groking the problem...
Try sorting the array, before processing it, and leverage that when you run through it. This has a better runtime complexity.
$arr = array(0,0,1,2,2,5,6,7,7,9,10,10);
asort($arr);
$n = 2;
$cnt = count($arr);
$counts = array_pad(array(), $cnt, 0);
for ($x=0; $x<$cnt; $x++) {
$low = $x - 1;
$lower_range_bound = $arr[$x]-$n;
while($low >= 0 && ($arr[$low] >= $lower_range_bound)) {
$counts[$x]++;
$low--;
}
$high = $x + 1;
$upper_range_bound = $arr[$x]+$n;
while($high < $cnt && $arr[$high] <= $upper_range_bound) {
$counts[$x]++;
$high++;
}
}
print_r($arr);
print_r($counts);
Play with it here: http://codepad.org/JXlZNCxW
Suppose I have two arrays:
$a1 = array(0, 1, 2);
$a2 = array(3, 4, 5);
I want to be able to do a merge technique that alternates the array values and not just concatenate them. I want this result:
array(0, 3, 1, 4, 2, 5);
Is there a native way to do this as performance is an issue here since I need to do this thousands of times
Please note, I know I can do it like this:
for (var $i = 0; $i < count($a1); $i++) {
newArray[] = $a1[$i];
newArray[] = $b1[$i];
}
I'm looking for a built in way if there is a faster one.
$count = count($a1);
for ($i = 0; $i < $count; $i++) {
$newArray[] = $a1[$i];
$newArray[] = $b1[$i];
}
My work here is done.
$a1 = array(0,1,2);
$a2 = array(3,4,5);
$start = microtime(TRUE);
for($t = 0; $t < 100000; $t++)
{
$newArray = array();
$count = count($a1);
for ($i = 0; $i < $count; $i++)
{
$newArray[] = $a1[$i];
$newArray[] = $a2[$i];
}
}
echo round(microtime(TRUE) - $start, 2); # 0.6
$a1 = array(0,1,2);
$a2 = array(3,4,5);
$start = microtime(TRUE);
for($t = 0; $t < 100000; $t++)
{
$newArray = array();
for ($i = 0; $i < count($a1); $i++)
{
$newArray[] = $a1[$i];
$newArray[] = $a2[$i];
}
}
echo round(microtime(TRUE) - $start, 2); # 0.85
So pre-counting array size will be ~1/4 [citation needed] (on freakin' 100.000 iterations you will gain 0.2 in total) faster. If you put count() inside loop, it will recount on every iteration. 1/4 seems to me a reasonably faster. If you are looking for compiled function, you can stop.
P.S. Benchmark is like bikini, it shows you everything, and nothing.
Since you are "zippering" two indexed arrays, you can "transpose and flatten". I expect that this will not be quite as fast as using a for() or foreach(), but on small input arrays, there will be no noticeable drag on performance. In other words, when coding style or minimal declared variables is sought, then the following technique should be considered.
Code: (Demo)
$a1 = [0, 1, 2];
$a2 = [3, 4, 5];
var_export(
array_merge(...array_map(null, $a1, $a2))
);
Output:
array (
0 => 0,
1 => 3,
2 => 1,
3 => 4,
4 => 2,
5 => 5,
)
As a funky little function-less approach, you can push the $a1 value from the foreach() value declaration and inside the loop's body, you can push the $a2 value. Feast your eyes... (Demo)
$result = [];
foreach ($a1 as $index => $result[]) {
$result[] = $a2[$index];
}
var_export($result);
// same output as earlier snippet
For anyone that is hunting for an associative-safe technique, you could make looped slice or splice calls. Be aware that splice() will mutate/consume the input arrays in the process. (Slice Demo) (Splice Demo)
$result = [];
for ($i = 0, $count = count($a1); $i < $count; ++$i) {
$result += array_slice($a1, $i, 1)
+ array_slice($a2, $i, 1);
}
or
$result = [];
while($a1 && $a2) {
$result += array_splice($a1, 0, 1)
+ array_splice($a2, 0, 1);
}
p.s. I even build this utility snippet to offer more dynamic tooling of how many elements should be inserted and how frequently from each array while merging. See Insert elements from one array (one-at-a-time) after every second element of another array (un-even zippering).
I have a array of say 50 elements. This array can be of size anything.
I want to have the first 10 elements of the array in a string.
I have the program as:
$array1= array("itself", "aith","Inside","Engineer","cooool","that","it","because");
$i=0;
for($f=0; $f < sizeof(array1); $f++)
{
$temparry = $temparry.array1[$f];
if(($f%10) == 0 && ($f !== 0))
{
$temparray[$i] = $temparray;
$i++;
}
}
==
so that at the end:
I get
temparray1= first 10 elements
temparray2 - next 10 elemnts...
I am not what I am missing in my loops.
After reading your comment, I think you want array_chunk [docs]:
$chunks = array_chunk($array1, 10);
This will create a multidimensional array with each element being an array containing 10 elements.
If you still want to join them to a string, you can use array_map [docs] and implode [docs]:
$strings = array_map('implode', $chunks);
This gives you an array of strings, where each element is the concatenation of a chunk.
This is something you can easily do with array_splice and implode.
Example:
<?php
$array = range(1, 50);
while ( $extracted = array_splice($array, 0, 10) )
{
// You could also assign this to a variable instead of outputting it.
echo implode(' ', $extracted);
}
all you are doing here is creating a temporary value and then deleting it. To save it into a string:
$myArray = array("itself", "aith","Inside","Engineer",
"cooool","that","it","because");
$myString = '';
for($i = 0; $i < 10; $i++) {
$myString .= $myArray[$i];
}
You could also run that inside of another for loop that would run through the entire array giving you ten-element increments.
Actually you can use arrray_slice and implode functions like this:
// put first 10 elements into array output
$output = array_slice($myArray, 10);
// implode the 10 elements into a string
$str = implode("", $output);
OP's fixed code as per comments below:
$array1= array("itself","aith","Inside","Engineer","cooool","that","it","because");
$temparry='';
$temparray = array();
for($f=0; $f < count($array1); $f++)
{
$temparry = $temparry.$array1[$f];
if(($f%3) == 0 && ($f !== 0))
{
$temparray[] = $temparry;
$temparry = '';
}
}
print_r($temparray);