Adding values from two diffrent arrays php - php

I have got the two arrays with my code execution like shown below:
$one = array("IN","US","IN","JP");
$two = array("10","20","30","40");
In above case the sequence for each value is same. i.e. the fist value for IN = 10. For US = 20
I want to add the values for the same countries. So that for india i will have the total of 40.
I have no idea about solving this.

You can merge the two array and use the values from the first array as the index.
$one = array("IN","US","IN","JP");
$two = array("10","20","30","40");
$merge = array();
// Loop through the first array
foreach($one as $index => $value){
// If the country has not been set before, create the index
if(!isset($merge[$value]))
$merge[$value] = $two[$index];
else // Add the value if it's not the first time we 'see' this country
$merge[$value] += $two[$index];
}
Now if you do $merge['IN'], it would give you 40.
Result of var_dump:
array(3) {
["IN"]=> int(40)
["US"]=> string(2) "20"
["JP"]=> string(2) "40"
}

Related

how to convert from strings to int and split them character by character into another array

Using this function,prt_pattern("341","0"), to print out
0
00
00
000
I'm stuck at converting "341" into integer and store it each number the following was the result i wanted
array[0] = 3
array[1] = 4
array[2] = 1
The flow I'm going to plan for this function is, convert string into int and store it by character, and then find the highest value. After that using 2 for loop, 1st for loop is loop from largest number to 1 and 2nd loop is for looping the number if 4 = 4, print 0 else print " " and value at array[1] -= 1.
Hope anyone can help me with this.
This should work. First I create an array of each number inside the string (cast to integer), then find the highest number from it using the max function.
<?php
$array = (function ($str): array {
$a = [];
$strlen = strlen($str);
for($i = 0; $i < $strlen; $i++) {
$a[] = (int) $str[$i];
}
return $a;
})("3429");
var_dump($array);
/**
array(4) {
[0]=>
int(3)
[1]=>
int(4)
[2]=>
int(2)
[3]=>
int(9)
}
**/
var_dump(max($array)); //int(9)
Test it online here : http://sandbox.onlinephpfunctions.com/code/2e3446d4475c3d69215857ed33a2c1f94f628e0b
edit
As Barmar pointed out in the comments, its way easier to use PHPs function str_split like so:
$array = str_split("3429");
Which will create an array just like previous mentioned.
(I feel silly for not thinking of that function.)

Value from php array seems incorrect

I am having an issue with understanding why my array containing 3 elements must be sliced into 2 parts each. I wish to access a number I'm pushing into the array only however it seems to print out the index rather than the 'key' value I pushed into it ($number).
I have a 2d array I'm pushing an ID and an integer into, and then sort it :
$array = [[]];
array_push($array, $doc[_id], $number);
array_multisort($array);
I then filter any empty elements:
$array = array_filter($array); //remove null elements
This all works as id expect however the array looks like this by this point:
unrated.array(5)
{
[2]=> object(MongoId)#32 (1)
{ ["$id"]=> string(24) "57b99696ce2350100b000029" }
[3]=> object(MongoId)#31 (1)
{ ["$id"]=> string(24) "57b998ccce2350181700002b" }
[4]=> object(MongoId)#33 (1)
{ ["$id"]=> string(24) "57b99a84ce2350100b00002b" }
[5]=> int(2) [6]=> int(3)
}
Again, this is fine however it means when I loop over the array using the code below it appears to be longer than 3 elements, as I have to slice from 0-6 instead of 0-3:
$array = array_slice($array, 0, 6, true); //only get 3 elements from array
foreach ($array as $key => $value) {
echo $key; //prints out values from 1-5 weirdly.... should just print the $number value
$id = $value->{'$id'};
}
What I am trying to achieve is to find the element in the array with the lowest possible value that was pushed earlier (array_push($array, $doc[_id], $number);) however because I cannot understand why the array is split into 6 rather than 3 parts its even more confusing.
Question in short : How do I access the $number pushed into the array and why is my array 6 seemingly 6 in size when it contains only 3 elements.
Any help would be appreciated, thanks.
To be clear, array_push simply pushes one or more values onto the end of an array. The first argument of array_push is the array you wish to push the value(s) to, and any subsequent argument is a list of values you wish to push. So what you're doing with array_push($array, $doc[_id], $number) is pushing two values ($doc[_id] and $number) to the end of the array $array. array_push will just use the next available index as the key when it adds those values to the array. It will not allow you to specify a key. This is the same thing as doing $array[] = $value.
To specify a key you must assign a value directly to the array key like so: $array[$key] = $value.

PHP unique number in array

I am trying to generate 6 numbers in an array, I'm using the mt_rand function, however I can't have the same number in the array. How would I go about checking for this and generating the number again?
I've thought about making a duplicate array and looping throw and counting how many are in the array, if its more then 1 then re generating the numbers and checking again, however this just seems like a lot of work for something that php might have a native function for that I can't find...
The duplicate thing isn't what I need help with, that is checking the key to the value, I need all values to be unique.
$number_of_numbers = 6;//number_of_numbers in array
$min = 1;//minimum value of number that you want
$max = 15;//maximum value of number that you want
$array = array();
for ($a = 0; $a < $number_of_numbers; $a++) {
$check = 0;//for entering while loop
while ($check !== false) { //pick a number and check if it is in array if it is in the array, pick again and check again
$try[$a] = mt_rand($min, $max); //pick a number
$check = array_search($try[$a], $array);// search that number if it is in the array
}
$array[] = $try[$a]; //add number to array
}
var_dump($array); // show me the array
Is that what you mean? I may get misunderstood about the array keys. Can you explain it a little more?
here is the output. sorry i forgot to add it first.
array(6) { [0]=> int(10) [1]=> int(12) [2]=> int(3) [3]=> int(5) [4]=> int(9) [5]=> int(15) }

How to get more random elements from an array, than the array has?

I have this code to get 3 random values from my array:
$maps_clean = array_filter($find_league_maps);
$random_maps = array_rand($maps_clean,3);
$league_match_maps = ",".$maps_clean[1].",".$maps_clean[2].",".$maps_clean[3].",";
This works as long as the array has at least 3 values. Now I want to modify my code so that when I want more random values than I have in my array, it just gets new ones out of the array again. Yes, this means I can have some values more than once.
How would I do that?
You can use a simple while loop and shuffle() the array inside of it, then get as many random elements as you need with array_slice(). Now if you want more random values than you have array elements, it simple takes the entire array, goes into the next iteration and takes the rest which it needs from the new shuffled array.
Code
<?php
$arr = [1,2,3,4];
$random = 5;
$result = [];
while(count($result) != $random){
shuffle($arr);
$result = array_merge($result, array_slice($arr, 0, $random - count($result)));
}
print_r($result);
?>
You can replace the elements having the same keys of an array fill with values with your $maps_clean.
$maps_clean = array_replace(array_fill(1, 3, null), array_filter($find_league_maps));
Here array_fill returns:
array(3) {
[1]=>
NULL
[2]=>
NULL
[3]=>
NULL
}
and its elements are replaced by the elements returned by array_filter($find_league_maps) that have the same keys.
The array key is start from 0 by default so, try with
$league_match_maps = ",".$maps_clean[0].",".$maps_clean[1].",".$maps_clean[2].",";
also what is the output of count($maps_clean)?

Using PHP, randomly pair up group of items, not pairing any with itself, no direct pairings

Assume you have a set of items in an array.
A, B, C, D, E, F, G, H
Using PHP, how would you randomly pair the letters together without pairing them with a duplicate of themselves?
Such as this:
A->pairedLetter = G
B->pairedLetter = C
C->pairedLetter = E
D->pairedLetter = A
E->pairedLetter = B
F->pairedLetter = D
G->pairedLetter = F
and so on...
EDIT:
Oh, and also, If A is paired with F, F can NOT be paired with A.
So there will have to be as many relationships as there are items.
What about this ?
// input array
$arr = array('A','B','C','D','E','F');
// result array
$res = array();
// get first element and save it
$first = $ele1 = array_shift($arr);
while(count($arr)) {
// get random element
$ele2 = array_rand($arr);
// associate elements
$res[$ele1] = $arr[$ele2];
// random element becomes next element
$ele1 = $arr[$ele2];
// delete the random element
array_splice($arr, $ele2, 1);
}
// associate last element woth the first one
$res[$ele1] = $first;
print_r($res);
Output:
Array
(
[A] => B
[B] => F
[F] => E
[E] => D
[D] => C
[C] => A
)
Works with even number of elements arrays as well as odd.
Update, using Chris' algorithm:
$arr = array('A','B','C','D','E','F');
shuffle($arr);
$res=array();
for($i=0;$i<count($arr);$i++) {
$res[$arr[$i]] = $arr[$i+1];
}
$res[$arr[count($arr)-1]] = $arr[0];
Does it have to be perfectly random given your constraints? If you were willing to add in another constraint then you could make the problem very simple. If you were willing to make it so that the mappings all formed a single loop then you could just shuffle your array and then make element one pont at two, two point at three and the last element points at the first. You will guarantee that no element can poitn at itself (unless the array only has one element), no element will point at the element pointing at it (unless the array only has two elements) and that no element will be pointed at by more than one item.
You are restricting your results set slightly so losing a certain amount of the random element but if you are happy with this its extremely simpel to do.
Duplicate the array.
Call shuffle on one array.
Then:
Check that the first elements are different (if they are switch the first two elements of one array).
array_pop off an item from each array to form a pair.
If the items are the same, pop two off one array and pair up, then two off the other.
edit
With your extra condition, you'll need to check that every pair doesn't already exist. If it does (at the third stage) you can try taking different combinations (pop off first and third {pop off first, second, third and push second back on}) but you may still end up with an invalid pair at the end so would need to start again.
$array = array(
'A','B','C',
'D','E','F',
'G','H','I','J'
);
$new = array();
if(count($array) % 2 != 0)
{
array_pop($array); // Got to remove 1 element to make them even.
}
foreach($array as $item)
{
$_t = array_pop($array);
//Key
if(!isset($new[$item]))
{
$new[$item] = $_t;
$new[$_t] = $item;
}
}
var_dump($new);
This would print:
array(10){
["A"]=> string(1) "J"
["J"]=> string(1) "A"
["B"]=> string(1) "I"
["I"]=> string(1) "B"
["C"]=> string(1) "H"
["H"]=> string(1) "C"
["D"]=> string(1) "G"
["G"]=> string(1) "D"
["E"]=> string(1) "F"
["F"]=> string(1) "E"
}
the way this works is it loops the values and deletes a value at the same time, so you always have 2 values at once but at the same time shrinking the array by 1.
then when we set the new keys were setting both of them to the new array, so the next time the loop iterates if the same value comes back around it just gets discarded :)
I've tried using a copy of the original array and using array_rand() but if it finds the same item as I'm iterating over, I have to run array_rand() again, which can fall into a endless loop.
I'm stumped, there has to be an elegant way to do this.
$arrayValues = range('A','H');
shuffle($arrayValues);
while (count($arrayValues) > 0) {
echo array_pop($arrayValues),' is matched with ',array_pop($arrayValues),'<br />';
}
EDIT
following changes to the question
$arrayValues = range('A','H');
$tmpArrayValues = $arrayValues;
$pairs = array();
shuffle($tmpArrayValues);
foreach($arrayValues as $arrayValue) {
$tmpValue = array_pop($tmpArrayValues);
while (($arrayValue == $tmpValue) || ((isset($pairs[$tmpValue])) && ($pairs[$tmpValue] == $arrayValue))) {
array_unshift($tmpArrayValues,$tmpValue);
$tmpValue = array_pop($tmpArrayValues);
}
$pairs[$arrayValue] = $tmpValue;
}
foreach($pairs as $key => $value) {
echo $key,' is matched with ',$value,'<br />';
}
Using the shuffle function on the array and checking that the mappings are valid (A doesn't map to A and that if A maps to B then B doesn't map to A). The following should do what you want:
$values = array('A','B','C','D','E','F','G');
$new_values = array('A','B','C','D','E','F','G');
$random = shuffle($new_values);
//randomly shuffle the order of the second array
$mappings = array();
$validMappings = false;
//continue to retry alternative mappings until a valid result is found
while(!$validMappings) {
//set the mappings from $values to $new_values
for($i = 0; $i < count($values); $i++) {
$mappings[$values[$i]] = $new_values[$i];
}
$validMappings = true;
//check validity of the current mapping
foreach ($mappings as $key=>$value) {
if($mappings[$key] == $mappings[$value]) {
$validMappings = false;
break;
}
}
//if false shuffle the new values and test again
if(!$validMappings) {
$random = shuffle($new_values);
}
}
print_r($mappings);

Categories