I have the following scenario
$elementsInPairs = ["xyz","xxx","yyy","zzz"];
$valuesInPair =[4,2,3,1];
and i need to sort the second array which would give me
[1,2,3,4]
which i can do by
sort($valuesInPair)
but i need the same to happen in first array as well, based on the sorting of the second array
["zzz","xxx","yyy","xyz"];
EDIT
As i had to fix it urgently, i guess i wasn't able to share more information, and the question seemed vague
basically the idea is that i have two sets of arrays, same number of elements in all cases, and they are linked to each other, The second array is a set of order IDs. and first array is set of names,
so in the above example, i have
4 relates to xyz
2 relates to xxx
3 relates to yyy
1 relates to zzz
So i need to sort based on IDs, and have the same order reflect in the first array as well,
so the final result would be,
["zzz","xxx","yyy","xyz"];
which is sorted based on
[1, 2, 3, 4];
Hopefully this clears things above
You can achieve this by using array_multisort method.
array_multisort($valuesInPair, SORT_ASC, $elementsInPair);
Use this below code, this does exactly what you're looking for.
$elementsInPairs = ["xyz","xxx","yyy","zzz"];
$valuesInPair =[4,2,3,1];
$data = array_combine($elementsInPairs,$valuesInPair);
asort($data);
$dumpdata = [];
foreach($data as $x => $x_value) {
$dumpdata[] = $x;
}
print_r($dumpdata);
I hope this helps you.
You kan do like this :
<?php
$elementsInPairs = ["xyz","xxx","yyy","zzz"];
$valuesInPair =[4,2,3,1];
//use [asort][1] - Sort an array in reverse order and maintain index association
asort($valuesInPair);
// and make a new array to sort elementsInPairs
$newelementsInPairs = array();
foreach($valuesInPair as $key=>$val){
$newelementsInPairs[] = $elementsInPairs[$key];
}
print_r(implode(",",$valuesInPair)."\n");
print_r(implode(",",$newelementsInPairs));
/** Output
1,2,3,4
zzz,xxx,yyy,xyz
**/
Hi please combine two array and sort
$newArray =array_combine($valuesInPair,$elementsInPairs);
then sort($newArray);
You can use array_combine(), ksort() and array_values():
<?php
$elementsInPairs = ["xyz","xxx","yyy","zzz"];
$valuesInPair = [4,2,3,1];
$newArray = array_combine($valuesInPair, $elementsInPairs);
ksort($newArray);
$sortedElements = array_values($newArray);
print_r($sortedElements);
will output
Array
(
[0] => zzz
[1] => xxx
[2] => yyy
[3] => xyz
)
Related
I have a seemingly simple ranking-type problem associated with php arrays, unfortunately after much research it has defeated me:
I have a simple array where the keys are names of people and the values are just associated numbers:
$myArray = Array("David"=>36, "James"=>24, "Sarah"=>70, "Mary"=>55);
Here’s the challenge: Given a name, what is their rank within the array? For example: Sarah=rank1; It seems simple because I figured I could just sort the array by the values then loop though to the required name to get the rank. However, weirdly when I sort the array it just unhelpfully returns 1!
print_r(asort($myArray)) = 1 (??)
I suppose I could put the array in an MySQL table but that seems a bit heavy handed. Is anyone aware of a php solution? Where am I going wrong with the sort? I've read the documentation here and it seems asort is the appropriate function (preserves association and sorts on values).
Thanks
The Grinch
(Edited - works now)
Kind of ugly but this should work:
arsort($origArr);
$rankedArr = array_keys($origArr);
foreach ($rankedArr as $rank => $person) {
if ($person == 'Sarah') {
echo $rank + 1;
break;
}
}
What you're doing is first sorting by values, then you're dropping those values and just getting an indexed list of people. Their key value + 1 is their rank. (because first is 0, right?)
EDIT2 - slightly cleaner:
arsort($origArr);
$rankedArr = array_keys($origArr);
$finalRanks = array_flip($rankedArr);
$rank = $finalRanks['Sarah'] + 1;
:-)
asort function returns a boolean and sort the given array as a reference
var_dump(asort($myArray)) = bool(true)
If you print_r($myArray) after this previous line, you'll get your sorted array in $myArray
EDIT: Re-read.
Try doing this to get your ranking numerously:
<?php
/* asort = Lower num to Upper */
asort($myArray);
/* arsort = Upper one to lower */
// arsort($myArray);
$ranks = array_fill(1,count($myArray),'foo');
$ranked = array_combine(array_flip($myArray),array_keys($ranks));
/* Output */
print_r($ranked);
/* Array ( [James] => 1 [David] => 2 [Mary] => 3 [Sarah] => 4 ) */
?>
asort returns bool value, as described here.
I have an array like this one
$state[1]='FG';
$state[2]='BU';
$state[3]='CA';
...
$state[150]='YT'
What I need is to have the $state array ordered from A to Z and maintain, in some structure, the original order of the array.
Something like:
$state_ordered['BU']=2;
$state_ordered['CA']=3;
and so on.
I have the array in the first form in an include file: which is the most performant way and which is the related structure to use in order to have the best solution?
The include is done at each homepage opening...
Thanks in advance,
A.
Well, you can array_flip the array, thus making 'values' be the original indexes, and then sort it by keys...
$b = array_flip($a);
ksort($b);
then work with $b keys , but the values reflect original order
You want array_flip(), which switches the key and value pairs.
Example #2 from the link:
$trans = array("a" => 1, "b" => 1, "c" => 2);
$trans = array_flip($trans);
print_r($trans);
Outputs:
Array
(
[1] => b
[2] => c
)
PHP has quite a few functions for sorting arrays. You could sort your array alphabetically by the values it holds by using asort() and then retrieve the index using array_search()
as such:
?php
$state[1]='FG';
$state[2]='BU';
$state[3]='CA';
asort($state);
$key = array_search('BU',$state);
print $state[$key] . PHP_EOL;
print_r($state);
this will output
BU
Array
(
[2] => BU
[3] => CA
[1] => FG
)
which as you can see keeps the original index values of your array. This does mean however that when you loop over your array without using the index directly, like when you use foreach that you then loop over it in the resorted order:
foreach($state as $key=>$value){
print "$key: $value" . PHP_EOL;
}
2: BU
3: CA
1: FG
You'd need to use ksort on the array first to sort it by index again before getting the regular foreach behaviour that you'd probably want/expect.
ksort($state);
foreach($state as $key=>$value){
print "$key: $value" . PHP_EOL;
}
1: FG
2: BU
3: CA
Looping using a for structure with numeric index values always works correcty of course. Be warned that these functions get passed your array by reference, meaning that they work on the 'live array' and not on a copy, you'll need to make your own copy first if you want one, more info in References Explained.
Assume that i have the following arrays containing:
Array (
[0] => 099/3274-6974
[1] => 099/12-365898
[2] => 001/323-9139
[3] => 002/3274-6974
[4] => 000/3623-8888
[5] => 001/323-9139
[6] => www.somesite.com
)
Where:
Values that starts with 000/, 002/ and 001/ represents mobile (cell) phone numbers
Values that starts with 099/ represents telephone (fixed) numbers
Vales that starts with www. represents web sites
I need to convert given array into 3 new arrays, each containing proper information, like arrayTelephone, arrayMobile, arraySite.
Function in_array works only if i know whole value of key in the given array, which is not my case.
Create the three empty arrays, loop through the source array with foreach, inspect each value (regexp is nice for this) and add the items to their respective arrays.
Loop through all the items and sort them into the appropriate arrays based on the first 4 characters.
$arrayTelephone = array();
$arrayMobile = array();
$arraySite = array();
foreach($data as $item) {
switch(substr($item, 0, 4)) {
case '000/':
case '001/':
case '002/':
$arrayMobile[] = $item;
break;
case '099/':
$arrayTelephone[] = $item;
break;
case 'www.':
$arraySite[] = $item;
break;
}
}
You can loop over the array and push the value to the correct new array based on your criteria. Example:
<?php
$fixed_array = array();
foreach ($data_array as $data) {
if (strpos($data, '099') === 0) {
$fixed_array[] = $data;
}
if ....
}
Yes i actually wrote the full code with preg_match but after reading some comments i accept that its better to show the way.
You will create three different arrays named arrayTelephone, arrayMobile, arraySite.
than you will search though your first array with foreach or for loop. Compare your current loop value with your criteria and push the value to one of the convenient new arrays (arrayTelephone, arrayMobile, arraySite) after pushing just continue your loop with "continue" statement.
You can find the solution by looking add the Perfect PHP Guide
I have this array:-
Array ( [0] => Prefectorial Board/Prefect/2011 [1] => Prefectorial Board/Head Prefect/2011 [2] => Class Positions/Head Prefect/2011 [3] => Prefectorial Board/Head Prefect/2011 )
How to detect this array have duplicate value and I want the participant to re-fill in his data.
I have try to use this method to detect:-
$max = max(array_values($lr_str));
$keys = array_keys($lr_str, $max);
but it seem like not work for me.
any idea on this?
thanks for advance.
I do not know if I understand you correctly, but you can test the array has duplicated values by using this:
if (count($your_array) === count(array_unique($your_array)) {
// array has no duplicated values
} else {
// array has duplicated values - see compared arrays
}
Are you looking for array_unique?
You can use array_unique() to remove duplicate values. If no values were removed then the returned array should have the same number of items as the original:
if(count($lr_str) == count(array_unique($lr_str))){
//tell participant to re=fill their data
}
This is the set of result from my database
print_r($plan);
Array
(
[0] => Array
(
[id] => 2
[subscr_unit] => D
[subscr_period] =>
[subscr_fee] =>
)
[1] => Array
(
[id] => 3
[subscr_unit] => M,Y
[subscr_period] => 1,1
[subscr_fee] => 90,1000
)
[2] => Array
(
[id] => 32
[subscr_unit] => M,Y
[subscr_period] => 1,1
[subscr_fee] => 150,1500
)
)
How can I change the $plan[0] to $plan[value_of_id]
Thank You.
This won't do it in-place, but:
$new_plan = array();
foreach ($plan as $item)
{
$new_plan[$item['id']] = $item;
}
This may be a bit late but I've been looking for a solution to the same problem. But since all of the other answers involve loops and are too complicated imho, I've been trying some stuff myself.
The outcome
$items = array_combine(array_column($items, 'id'), $items);
It's as simple as that.
You could also use array_reduce which is generally used for, well, reducing an array. That said it can be used to achieve an array format like you want by simple returning the same items as in the input array but with the required keys.
// Note: Uses anonymous function syntax only available as of PHP 5.3.0
// Could use create_function() or callback to a named function
$plan = array_reduce($plan, function($reduced, $current) {
$reduced[$current['id']] = $current;
return $reduced;
});
Note however, if the paragraph above did not make it clear, this approach is overkill for your individual requirements as outlined in the question. It might prove useful however to readers looking to do a little more with the array than simply changing the keys.
Seeing the code you used to assemble $plan would be helpful, but I'm going assume it was something like this
while ($line = $RES->fetch_assoc()) {
$plan[] = $line;
}
You can simply assign an explicit value while pulling the data from your database, like this:
while ($line = $RES->fetch_assoc()) {
$plan[$line['id']] = $line;
}
This is assuming $RES is the result set from your database query.
In my opinion, there is no simpler or more expressive technique than array_column() with a null second parameter. The null parameter informs the function to retain all elements in each subarray, the new 1st level keys are derived from the column nominated in the third parameter of array_column().
Code: (Demo)
$plan = array_column($plan, null, 'id');
Note: this technique is also commonly used to ensure that all subarrays contain a unique value within the parent array. This occurs because arrays may not contain duplicate keys on the same level. Consequently, if a duplicate value occurs while using array_column(), then previous subarrays will be overwritten by each subsequent occurrence of the same value to be used as the new key.
Demonstration of "data loss" due to new key collision.
$plans = array();
foreach($plan as $item)
{
$plans[$item['id']] = $item;
}
$plans contains the associative array.
This is just a simple solution.
$newplan = array();
foreach($plan as $value) {
$id = $value["id"];
unset($value["id"]);
$newplan[$id] = $value;
}