I need to add an item every 6th position.
So it would look like this:
[
//item1
//item2
//item3
//item4
//item5
//NEW ITEM HERE
//item7
//item8
//item9
//item10
//item11
//NEW ITEM
]
I already tried this:
foreach($ports as $key => $port)
{
if($key %9 == 2) {
$ports->splice($key, 0, [$ads]);
}
}
But that's not working any idea?
Use array_chunk and add element to each of sub-arrays:
$portsChunks = array_chunk($ports, 5); // Split array to sub-arrays of max-5 elements.
// Add new element if chunk is full length.
// Means last one will not receive new element if it's shorter than 5
array_walk($portsChunks, function (&$array) {
if (count($array) == 5) {
$array[] = 'New Item';
}
});
// Use arguments unpacking to pass all chunks to array_merge
$ports = array_merge(...$portsChunk);
Example
You can use foreach loop:
$ports = range(1,50);
$new_ports = [];
foreach ($ports as $key => $port) {
$new_ports[] = $port;
if(!(($key+1)%5))
$new_ports[] = 'New item';
}
print_r($new_ports);
$ports = [1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6];
$ports = array_chunk($ports, 5);
foreach ($ports as &$port){
array_push($port, 'new value');
}
unset($port);
if(count($ports[count($ports)-1]) < 6){
array_pop($ports[count($ports)-1]);
}
$ports = array_merge(...$ports);
you just need a new array to hold all of your data. and then you iterate over your old array and after each 5th position insert a new element. something like this
$result = [];
$ports = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
$porstCount = count($ports);
for ($i = 0; $i < $portsCount; $i++) {
$result[] = $ports[$i];
if ($i > 0 && $i % 5 === 0) {
$result[] = 'new element';
}
}
// $result will be [1, 2, 3, 4, 5, 'new element', 6, 7, 8, 9, 10, 'new element', 11, 12]
I hope below case solves your problem:
$newarr = array();
$cnt = 1;
foreach($arr as $key=>$value){
$newarr[] = $value;
if($cnt%5 == 0){
$newarr[] = 'this is new item';
}
$cnt++;
}
print_r($newarr);
Related
I'm trying to combine the scores of employee for my program. My sample is one employee is evaluated more than one. So basically, if employee 1 have scored of 87 and 90 the total should be 177. After computation, I need to return the result with the highest score.
Here so far my sample code (I simplified my code for this question because it is too long to post the original code):
$scores = array(
array(1, "allan", 90),
array(2, "allan", 85),
array(3, "mark", 100),
array(4, "jason", 88),
array(5, "allan", 92),
array(6, "mark", 77),
array(7, "mark", 88),
array(8, "jason", 90)
);
print_r($scores);
get_topemployee($scores);
function get_topemployee($scores) {
$total_score = 0;
$combined_score = array();
foreach($scores as $key) {
for($i=0; count($scores) <= $i; $i++) {
if($key[0] == $key[0][$i]) {
$total_score += $key[1];
}
$combined_score[] = array($key[0], $key[1], $total_score);
}
}
$employee = ""; // employee with highest score
$compare_score = 0;
foreach($combined_score as $value) {
$compare_score = $value[1];
if($value[1] >= $compare_score) {
$employee = $value[0];
}
}
return $employee;
}
The result does not return the employee with highest score and not sure which in my code is incorrect. thanks for help
do this:- https://3v4l.org/WhVaN
You can use array_reduce to convert your scores array into an array of total scores indexed by employee:
$scores = array_reduce($scores, function ($c, $v) {
$name = $v[1];
if (isset($c[$name])) {
$c[$name] += $v[2];
}
else {
$c[$name] = $v[2];
}
return $c;
}, array());
You can then use arsort to sort the array in reverse order while maintaining the key association. You can then use key to get the key of the first element, which will be the name of the employee with the highest score:
arsort($scores);
echo key($scores);
Output:
allan
Demo on 3v4l.org
To print out all the scores, you can simply print_r($scores):
Array (
[allan] => 267
[mark] => 265
[jason] => 178
)
Alternatively to print just the highest score, change echo key($scores); to echo key($scores) . ' ' . current($scores);:
allan 267
Updated demo.
You can do that with simple foreach loop:
foreach($scores as $e) {
if (!isset($res[$e[1]])) $res[$e[1]] = 0;
$res[$e[1]] += $e[2];
}
print_r(array_keys($res, max($res)));
Live example: 3v4l
Here is a snippet for you, please see inline doc for explanation
$result = [];
array_walk($scores, function($item) use(&$result){
// pushing on the behalf of name and checking if not isset with '??'
$result[$item[1]] = ($result[$item[1]] ?? 0) + $item[2];
});
// searching for index with max value in result and show max value too
echo array_search(max($result), $result).' -> '. max($result);
array_search — Searches the array for a given value and returns the first corresponding key if successful
array_walk — Apply a user supplied function to every member of an array
Output
allan -> 267
Demo Link.
$scores = [
[1, 'allan', 90],
[2, 'allan', 85],
[3, 'mark', 100],
[4, 'jason', 88],
[5, 'allan', 92],
[6, 'mark', 77],
[7, 'mark', 88],
[8, 'jason', 90]
];
function maxScore(array $scores): string {
$preparedScores = [];
foreach ($scores as $score) {
$key = $score[1];
$value = $score[2];
if (isset($preparedScores[$key])) {
$preparedScores[$key] += $value;
} else {
$preparedScores[$key] = $value;
}
}
arsort($preparedScores);
return array_key_first($preparedScores);
}
echo maxScore($scores);
Result:
allan
$scores = array(
array(1, "allan", 90),
array(2, "allan", 85),
array(3, "mark", 100),
array(4, "jason", 88),
array(5, "allan", 92),
array(6, "mark", 77),
array(7, "mark", 88),
array(8, "jason", 90)
);
get_topemployee($scores);
function get_topemployee($scores) {
$total_score = 0;
$combined_score = array();
$highest_score = 0;
$highest_employee = '';
foreach($scores as $key => $value) {
if ( ! isset($combined_score[$value[1]])) {
$combined_score[$value[1]] = $value[2];
}
else {
$combined_score[$value[1]] += $value[2];
}
if ($highest_score < $combined_score[$value[1]]) {
$highest_score = $combined_score[$value[1]];
$highest_employee = $value[1]; //the highest value employee
}
}
return $highest_employee;
}
For example, in php
$arr = [9, 4, 3, 5, 2, 6];
then,
$output = [[0,0], [1,2], [2,2], [1,1], [4,1], [1,0]];
[0, 0] = the bigger elements of 9 is 0 on both side
[1, 2] = the bigger elements of 4 is 1 (9) on left and 2 (5, 6) on right side ... [ 9 > 4] - [ 5 > 4, 6 > 4 ]
[2, 2] = the bigger elements of 3 is 2 (9, 4) on the left and 2 (5, 6) on right side
[1, 1] = the bigger elements of 5 is 1 (9) on the left and 1 (6) on the right side
[4, 1] = the bigger elements of 2 (9, 4, 3, 5) is 4 on the left and 1 (6) on the right side
[1, 0] = the bigger elements of 6 is 1 (9) on the left and 0 (no elements after 6) on the right side
I want it in O(n log(n)), is it possible?
Looks like lots of answers already, you could do this with some of the array functions like some of the answers did, but since this is probably for your homework best to keep it simple. I keep track of whether it's left or right that should be incremented each iteration by using the $side variable.
$arr = [9, 4, 3, 5, 2, 6];
$results = [];
for ($x = 0; $x < count($arr); $x++) {
$results[$x] = [0,0];
$side = 0;
for ($y = 0; $y < count($arr); $y++) {
if ($arr[$y] > $arr[$x]) {
$results[$x][$side]++;
} elseif ($arr[$x] == $arr[$y]) {
$side = 1;
}
}
}
You need to loop through $arr to get each value, and then, in the loop, loop again through $arr to get the other values. Then, in the second loop, you build your output array by comparing both the value (to know if the number is, indeed, bigger) and the key (to know if it's on the left or the right).
$arr = array(9, 4, 3, 5, 2, 6);
$output = array();
foreach ($arr as $key=>$value) {
$out = array(0, 0);
foreach ($arr as $key2=>$value2) {
if ($key2 == $key) # If it's the same element
continue;
if ($value2 > $value) {
if ($key2 < $key)
$out[0]++;
else
$out[1]++;
}
}
$output[] = $out;
}
print_r($output);
See the output here.
Try this:
function fix_array($array) {
$return_array = array();
foreach ($array as $i => $value){
$left = array_slice($array, 0, $i);
$count_left = count(array_filter($left, function($var) use($value){
return $var > $value;
}));
$right = array_slice($array, $i + 1);
$count_right = count(array_filter($right, function($var) use($value){
return $var > $value;
}));
$return_array[] = [$count_left, $count_right];
}
return $return_array;
}
$arr = [9, 4, 3, 5, 2, 6];
$new_array = fix_array($arr);
print_r($new_array);
Simply compare it with left and right values. Try this:
$arr = [9, 4, 3, 5, 2, 6];
$total = count($arr);
$new_arr=array();
foreach ($arr as $key => $value) {
$left = 0;
$right = 0;
for ($i=0; $i < $total; $i++) {
if($key > $i && $arr[$i] > $arr[$key])
{
$left++;
}
elseif ($key < $i && $arr[$i] > $arr[$key]) {
$right++;
}
}
$new_arr[]=[$left,$right];
}
echo "<pre>";
print_r($new_arr);
Try the following code using array_walk()
<?php
$arr = [9, 4, 3, 5, 2, 6];
$finalArray =[];
array_walk($arr, function($value,$key) use(&$finalArray,&$arr) {
$param ['pre_val']=0;
$param ['post_val']=0;
$param ['current_index'] = $key;
$param ['current_value'] = $value;
$arr2 = $arr;
array_walk($arr2, function(&$value,$key) use(&$finalArray,&$param) {
if($key < $param['current_index']){
if($value > $param['current_value']){$param['pre_val'] ++;}
}else{
if($value > $param['current_value']){$param['post_val'] ++;}
}
$finalArray[$param['current_index']][0] = $param['pre_val'];
$finalArray[$param['current_index']][1] = $param['post_val'];
});
});
print_r($finalArray);
I have this array:
$arr = array(1, 2, 3, 4, 5, 6, 7, 8);
It has 8 value , i want to output all value after the fifth value which is 5.
so I want to output:
6 7 8
This is my code:
<?php
$arr = array(1, 2, 3, 4, 5, 6, 7, 8);
$i = 0;
while ($i < count($arr)) {
$a = $arr[$i];
echo $a ."\n";
$i++;
}
?>
Use array_slice()
$arr = array(1, 2, 3, 4, 5, 6, 7, 8);
$output = array_slice($arr, 0, 3);
Array_slice or starting your loops from the desired index:
<?php
$arr = array(1, 2, 3, 4, 5, 6, 7, 8);
$i = 5;
while ($i < count($arr)) {
$a = $arr[$i];
echo $a ."\n";
$i++;
}
?>
<?php
$arr = array(1, 2, 3, 4, 5, 6, 7, 8);
$arr = array_slice($arr,5);
$i = 0;
while ($i < count($arr)) {
$a = $arr[$i];
echo $a ."\n";
$i++;
}
?>
<?php
$arr = array(1, 2, 3, 4, 5, 6, 7, 8);
$i = 5;
while ($i < count($arr)) {
$a = $arr[$i];
echo $a ."\n";
$i++;
}
?>
Simply use array_slice along with implode function like as
$arr = array(1, 2, 3, 4, 5, 6, 7, 8);
echo implode("\n",array_slice($arr,5));
If you were testing it within browser you simply replace \n along with <br/>
Demo
I was just going through these questions for PHP and got stuck at one of them. The question is:
You have a PHP 1 dimensional array. Please write a PHP function that
takes 1 array as its parameter and returns an array. The function must
delete values in the input array that shows up 3 times or more?
For example, if you give the function
array(1, 3, 5, 2, 6, 6, 6, 3, 1, 9)the function will returnarray(1, 3, 5, 2, 3, 1, 9)
I was able to check if they are repeating themselves but I apply it to the array I am getting as input.
function removeDuplicate($array){
$result = array_count_values( $array );
$values = implode(" ", array_values($result));
echo $values . "<br>";
}
$qArray = array(1, 3, 5, 2, 6, 6, 6, 3, 1, 9);
removeDuplicate($qArray);
One more thing, we cannot use array_unique because it includes the value which is repeated and in question we totally remove them from the current array.
Assuming the value may not appear 3+ times anywhere in the array:
$array = array(1, 3, 5, 2, 6, 6, 6, 3, 1, 9);
// create array indexed by the numbers to remove
$remove = array_filter(array_count_values($array), function($value) {
return $value >= 3;
});
// filter the original array
$results = array_values(array_filter($array, function($value) use ($remove) {
return !array_key_exists($value, $remove);
}));
If values may not appear 3+ times consecutively:
$results = [];
for ($i = 0, $n = count($array); $i != $n;) {
$p = $i++;
// find repeated characters
while ($i != $n && $array[$p] === $array[$i]) {
++$i;
}
if ($i - $p < 3) {
// add to results
$results += array_fill(count($results), $i - $p, $array[$p]);
}
}
This should work :
function removeDuplicate($array) {
foreach ($array as $key => $val) {
$new[$val] ++;
if ($new[$val] >= 3)
unset($array[$key]);
}
return $array;
}
run this function i hope this help..
function removeDuplicate($array){
$result = array_count_values( $array );
$dub = array();
$answer = array();
foreach($result as $key => $val) {
if($val >= 3) {
$dub[] = $key;
}
}
foreach($array as $val) {
if(!in_array($val, $dub)) {
$answer[] = $val;
}
}
return $answer;
}
You can use this function with any number of occurrences you want - by default 3
function removeDuplicate($arr, $x = 3){
$new = $rem = array();
foreach($arr as $val) {
$new[$val]++;
if($new[$val]>=$x){
$rem[$val]=$new[$val];
}
}
$new = array_keys(array_diff_key($new, $rem));
return $new;
}
I think it is getting correct output. just try once.
$array=array(1,2,3,7,4,4,3,5,5,6,7);
$count=count($array);
$k=array();
for($i=0;$i<=$count;$i++)
{
if(!in_array($array[$i],$k))
{
$k[]=$array[$i];
}
}
array_pop($k);
print_r($k);
in this first $k is an empty array,after that we are inserting values into $k.
You should use array_unique funciton.
<?php
$q = array(1, 3, 5, 2, 6, 6, 6, 3, 1, 9);
print_r(array_unique($q));
?>
Try it and let me know if it worked.
$arr = array(1, 2, '...', '...', '...', 6, 7, 8, '...', 10);
array_unique creates: array(1, 2, '...', 6, 7, 8, 10);
I want the following: array(1, 2, '...', 6, 7, 8, '...', 10);
So basically, I'm looking for a fast way to remove only duplicates next to eachother.
$result = array();
$first = true;
foreach ($array as $x) {
if ($first || $x !== $previous) $result[] = $x;
$previous = $x;
$first = false;
}
Alter the $x !== $previous condition to suit your preferred definition of "duplicate". For example, array_unique does a loosely-typed comparison.
I would do it this way:
<?php
$arr = array(1, 2, '...', '...', '...', 6, 7, 8, '...', 10);
$el = $arr[0];
$out = $arr;
for ($i=1, $c = count($out); $i<$c; ++$i) {
if ($arr[$i] == $el) {
unset($out[$i]);
}
else {
$el = $out[$i];
}
}
$out = array_values($out);
foreach ($out as $i) {
echo $i."<br />";
}
Output:
1
2
...
6
7
8
...
10