Creating a list and indexing - php

Given a two list. Create a third list by picking an odd-index element from the first list and even index elements from the second.
For Example:
listOne = [3, 6, 9, 12, 15, 18, 21]
listTwo = [4, 8, 12, 16, 20, 24, 28]
Expected Output:
Printing Final third list
[6, 12, 18, 4, 12, 20, 28]

I think, it will be helpful for you.
<?php
$listOne = [3, 6, 9, 12, 15, 18, 21];
$listTwo = [4, 8, 12, 16, 20, 24, 28];
$NlistOne=[];
$NlistTwo=[];
//odd-index positions from list one [6, 12, 18]
foreach ($listOne as $key => $value) {
if($key%2==1){
array_push($NlistOne, $value);
}
}
//even-index positions from list two [4, 12, 20, 28]
foreach ($listTwo as $key => $value) {
if($key%2==0){
array_push($NlistTwo, $value);
}
}
//Printing Final third list [6, 12, 18, 4, 12, 20, 28]
print_r(array_merge($NlistOne,$NlistTwo));
?>
Output will be:
Array ( [0] => 6 [1] => 12 [2] => 18 [3] => 4 [4] => 12 [5] => 20 [6] => 28 )

//init result array
//loop over listOne, using for($i=1;$i<sizeof($listOne);$i=$i+2)
//and add to result for each iteration, $resultArr[] = $listOne[$i]
//do the same with listTwo, but for($i=*0*

You can merge both of arrays and then pick all odd elements
$listOne = [3, 6, 9, 12, 15, 18, 21];
$listTwo = [4, 8, 12, 16, 20, 24, 28];
$result = [];
foreach ( array_merge($listOne, $listTwo) as $value ){
if ( $key % 2 ) {
$result[] = $value;
}
}
If array length isn't fixed, say it could contain not 7 elements, then you need to check it before merging to make it have odd number of elements
$listOne = [3, 6, 9, 12, 15, 18, 21, 777];
$listTwo = [4, 8, 12, 16, 20, 24, 28];
$result = [];
if ( count($listOne) % 2 !== 1 ) {
$listOne[] = 0;
}
foreach( array_merge($listOne, $listTwo) as $value ){
if ( $key % 2 ) {
$result[] = $value;
}
}

you don't have to loop over whole array array_filter will do this for you, Constant ARRAY_FILTER_USE_KEY will check each key for odd or for even
<?php
$a1 = [3, 6, 9, 12, 15, 18, 21];
$a2 = [4, 8, 12, 16, 20, 24, 28];
function odd($var)
{
// returns whether the input integer is odd
return $var & 1;
}
function even($var)
{
// returns whether the input integer is even
return !($var & 1);
}
$result= (array_merge(array_filter($a1, 'odd', ARRAY_FILTER_USE_KEY),array_filter($a2, 'even', ARRAY_FILTER_USE_KEY)));
output you will get
Array (
[0] => 6
[1] => 12
[2] => 18
[3] => 4
[4] => 12
[5] => 20
[6] => 28 )

Iterate over first one and take only values of odds indices, and loop again through second one and take evens indices.
$listOne = [3, 6, 9, 12, 15, 18, 21];
$listTwo = [4, 8, 12, 16, 20, 24, 28];
$res = [];
for ($i=0; $i < count($listOne); $i++) {
if($i & 1) // $i is odd.
$res[] = $listOne[$i];
}
for ($j=0; $j < count($listTwo); $j++) {
if(n % 2 === 0) // $j is even.
$res[] = $listTwo[$j];
}
Result:
echo "List One :".json_encode($listOne)."<br>";
echo "List Two :".json_encode($listTwo)."<br>";
echo "Lists Merged:".json_encode($res);
Output:*
/*
List One :[3,6,9,12,15,18,21]
List Two :[4,8,12,16,20,24,28]
Lists Merged:[6,12,18,4,12,20,28]
*/

Iterate over arrays:
take odds in array starting with index One and increment it by two.
take evens in array by starting with index Zero and increment it by two.
$listOne = [3, 6, 9, 12, 15, 18, 21]; $listTwo = [4, 8, 12, 16, 20, 24, 28];
$res = [];
for ($i=1; $i < count($listOne); $i+=2) {
$res[] = $listOne[$i];
}
for ($j=0; $j < count($listTwo); $j+=2) {
$res[] = $listTwo[$j];
}
print(json_encode($res)); // [6,12,18,4,12,20,28]

Related

Sort an array of numbers by another predefined, non-exhaustive array of number, then sort ascending

Given two arrays $A1 and $A2, sort $A1 in such a way that the relative order among the elements will be same as those in $A2. For the elements not present in $A2, move them to the back of the array in ascending order.
$A1 = [2, 1, 2, 5, 7, 1, 9, 3, 6, 8, 8];
$A2 = [2, 1, 8, 3];
Desired output:
[2, 2, 1, 1, 8, 8, 3, 5, 6, 7, 9]
Coding attempt:
$sorted = array();
foreach($a1 as $key => $value) {
if(in_array($value, $a2)) {
$sorted[array_search($value, $a1)] = $value;
}
}
This can be done via for each loop :
$arr1 = array(2, 1, 2, 5, 7, 1, 9, 3, 6, 8, 8); // array to be sorted
$arr2 = array(2, 1, 8, 3); // refrence array for sort logic
// Output: A1[] = {2, 2, 1, 1, 8, 8, 3, 5, 6, 7, 9}
$sortarr = array(); // array to store final sorted values
foreach ($arr2 as $a) {
foreach ($arr1 as $k => $b) {
if($b==$a) {
$sortarr[]=$b;
unset($arr1[$k]);
}
}
}
$finalarr = array_merge($sortarr, $arr1);
print_r($finalarr);
You can use usort like this:
$k = array_flip($a2); // Create an associative array for the second array
usort($a1, function($a, $b) use ($k) {
return isset($k[$a]) ? (isset($k[$b]) ? $k[$a]-$k[$b] : -1) : (isset($k[$b]) ? 1 : $a-$b);
});
Other solutions that use a nested loop result in a time complexity of O(n²), while this has a time complexity of O(nlogn).
i tried this code and works:
<?php
/*
Input: A1[] = {2, 1, 2, 5, 7, 1, 9, 3, 6, 8, 8}
A2[] = {2, 1, 8, 3}
Output: A1[] = {2, 2, 1, 1, 8, 8, 3, 5, 6, 7, 9}
*/
$a1=array(2, 1, 2, 5, 7, 1, 9, 3, 6, 8, 8);
$a2=array(2, 1, 8, 3);
$a3=array();
sort($a1);//order array
//order array a3 with a2 value....
for($i=0;$i<sizeof($a2);$i++){
for($j=0;$j<sizeof($a1);$j++){
if($a1[$j]==$a2[$i]){
array_push($a3,$a2[$i]);
//if exsist value i change value in a1 in x
$a1[$j]="x";
}
}
}
//write in a3 the next number not present in a2
for($i=0;$i<sizeof($a1);$i++){
if($a1[$i]<>"x"){
array_push($a3, $a1[$i]);
}
}
print_r($a3);
//out:Array ( [0] => 2 [1] => 2 [2] => 1 [3] => 1 [4] => 8 [5] => 8 [6] => 3 [7] => 5 [8] => 6 [9] => 7 [10] => 9 )
?>
Hope this helps
I do not endorse the use of nested loops because they will be doing too many unnecessary cycles. #trincot's approach moreso represents what I would use in a professional application, but I will demonstrate a more modern and concise style with no iterated function calls.
Code: (Demo)
$arr1 = [2, 1, 2, 5, 7, 1, 9, 3, 6, 8, 8];
$arr2 = [2, 1, 8, 3];
$priority = array_flip($arr2);
$fallback = count($arr2);
usort(
$arr1,
fn($a, $b) =>
[$priority[$a] ?? $fallback, $a]
<=>
[$priority[$b] ?? $fallback, $b]
);
var_export($arr1);
// [2, 2, 1, 1, 8, 8, 3, 5, 6, 7, 9]
$arr2 is flipped into a lookup array, and count() is used when a value is not found in the lookup array. Whenever the first rule results in a tie, the second rule orders the numbers numerically in an ascending direction.
The meaning of custom function's syntax is:
[left value rule1, left value rule2] compared to [right value rule1, right value rule2]
The spaceship operator (<=>) will compare the corresponding element one at a time "rule1 vs rule1" then "rule2 vs rule2" as needed.

For-each loop, larger than 20 into another array

I'm stuck on this exercise that I can't seem to get for the life of me.
$numbers2 = [21, 5, 4, 6, 76, 2, 18, 85, 55, 1];
foreach ($numbers2 as &$value) {
$largeNumbers[] = $value > 20;
}
That's the code I have so far. What I am trying to do here is use a for-each loop to add all the numbers that are larger than 20 into another Array, which I have named $largeNumbers. The code I have inserted above seems to be printing out true and false values, which is not what I was going for. I'd really appreciate it someone could tell me what I'm possibly doing wrong or even show me a better way. I have to use a for-each loop.
For each item, you are checking if it's larger than 20, which results in a boolean value (it either is or is not), and you then store this value to the result array. Instead, you could use an if statement` to only take the elements that answer the condition:
foreach ($numbers2 as &$value) {
if ($value > 20) {
$largeNumbers[] = $value;
}
}
<?php
$nums = [21, 5, 4, 6, 76, 2, 18, 85, 55, 1];
$less_than_or_equal_to_20 = [];
foreach($nums as $v)
if($v <= 20)
$less_than_or_equal_to_20[] = $v;
$out = array_diff($nums, $less_than_or_equal_to_20);
var_export($out);
Output:
array ( 0 => 21, 4 => 76, 7 => 85, 8 => 55, )
<?php
$nums = [21, 5, 4, 6, 76, 2, 18, 85, 55, 1];
foreach([$nums] as $v)
$out = array_filter($v, function($v) {
return $v > 20;
});
var_export($out);
Output:
array ( 0 => 21, 4 => 76, 7 => 85, 8 => 55, )

Counting, highlighting and printing the duplicates between two arrays

First time posting on stackoverflow.
After printing the main array, I have managed to highlight the values that are found in the second one, but I also want to print the number of times that the duplicate occurs in brackets at the same time. I have run out of the ideas on how to do that last part, I get stuck in multiple loops and other problems. I will paste here what's working for now.
The code:
$main = array( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
12, 13, 14, 15, 16, 17, 18, 19, 20 );
$secondary = array( 1, 6, 10, 6, 17, 6, 17, 20 );
foreach ( $main as $number )
{
if ( in_array( $number, $secondary ) )
{
echo $item;
// this one is supposed to be highlighted, but the html code disappears on stackoverflow
/* this is where the number of duplicates should appear in bracket, example:
highlighted number( number of duplicates ) */
}
else
{
echo $item;
// this one is simple
}
}
EXPECTED RESULT:
1(1), 2, 3, 4, 5, 6(3), 7, 8, 9, 10(1), 11, 12, 13, 14, 15, 16, 17(2), 18, 19, 20(1)
Basically the brackets contain the number of times that the value is found in the second array, aside from being colored, but I can't paste the html code for some reason. Sorry for not making the expected result more clear !
PROBLEM SOLVED:
Thanks to everyone for your help, first time using this website, didn't expect such a quick response from you guys. Thank you very much !
You need to get the count values of your secondary array first using array_count_values. This is what you can acquire as
$main = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20);
$secondary = array(1, 6, 10, 6, 17, 6, 17, 20);
$count_values = array_count_values($secondary);
foreach ($main as $key => $value) {
if (in_array($value, $secondary)) {
echo $value . "<strong>(" . $count_values[$value] . ")</strong>";
echo ( ++$key == count($main)) ? '' : ',';
} else {
echo $value;
echo ( ++$key == count($main)) ? '' : ',';
}
}
Output:
1(1),2,3,4,5,6(3),7,8,9,10(1),11,12,13,14,15,16,17(2),18,19,20(1)
Assuming $secondary is the one with the dupes, you should go about it the other way:
$dupes = array();
foreach($secondary as $number) {
if (in_array($number, $main)) {
$dupes[$number]++;
}
}
var_dump($dupes);
<?php
$main = array( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,12, 13, 14, 15, 16, 17,18,19,20);
$secondary = array( 1, 6, 10, 6, 17, 6, 17, 20 );
$result =array();
foreach($main as $key => $value){
$i=0;
foreach($secondary as $key1 => $value1){
if($value == $value1){
$i++;
}
$result[$value] = $i;
}
}
$resultString ='';
foreach($result as $key => $value){
$resultString .=$key.'('.$value.'),' ;
}
echo trim($resultString,',');
?>
Result:
1(1),2(0),3(0),4(0),5(0),6(3),7(0),8(0),9(0),10(1),11(0),12(0),13(0),14(0),15(0),16(0),17(2),18(0),19(0),20(1)

remove elements in php array that occur more than twice

I am looking for a function in php,where the function must delete values in the array that shows up three times or more? For example, if you give the function array(2, 4, 6, 3, 7, 7, 7, 4, 2, 0) the funciton will return array(2, 4, 6, 3, 4, 2, 0)
You can use array_count_values() to get frequencies. Then use a foreach to get values that has frequency less than 3...
$array = array(2, 4, 6, 3, 7, 7, 7, 4, 2, 0);
$frq = array_count_values($array);
$result = array();
foreach ($frq as $key=>$value){
if ($value < 3){
$result[] = $key;
}
}
function FilterMyArray(array &$array){
$array_count=array_count_values($array);
foreach($array_count as $key => $value){
if($value > 2){
foreach (array_keys($array, $key, true) as $unsetKey) {
unset($array[$unsetKey]);
}
}
}
}
$array=array(1, 3, 5, 2, 6, 6, 6, 3, 1, 9);
FilterMyArray($array);
print_r($array);
Output
Array ( [0] => 1 [1] => 3 [2] => 5 [3] => 2 [7] => 3 [8] => 1 [9] => 9 )
`
This will remove all duplicates, but you'd have to add to it to count the number of each of the values.
$a = array(2, 4, 6, 3, 7, 7, 7, 4, 2, 0);
$b = array();
for ($a as $key=>$value) {
if (!in_array($value, $b)) {
$b[] = $value;
}
}
// array $b has all the values with no duplicates.

Create rows of elements based on an array of length values

Is there a neat way to split an array into chunks based on an array of lengths?
Input:
$start = range(0, 30);
$length = [3, 7, 2, 12, 6];
Desired Output:
[
[0, 1, 2], // 3
[4, 5, 6, 7, 8, 9, 10], // 7
[11, 12], // 2
[13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24], // 12
[25, 26, 27, 28, 29, 30], // 6
];
Using array_splice:
$target = array(); // or use [] in PHP 5.4
foreach($length as $i) {
$target[] = array_splice($start, 0, $i);
}
Try it.
Be advised, this changes $start!
This is very easily accomplished with the following:
Code:
$target = array();
$offset = 0;
foreach ($length as $lengthValue) {
$target[] = array_slice($start, $offset, $lengthValue);
$offset += $lengthValue;
}
var_dump($target);
Explanation:
What you are doing here is using the array_slice() method (very similar to the substr) to extract the portion of the array and then inserting it into the target array. Incrementing the offset each time allows the function to remember which one to use next time.

Categories