I have associative array. On print_f($array_name), I got this
Array (
[0] => Array (
[teamid] => abc
[distance] => 1.25
)
[1] => Array (
[teamid] => xyz
[distance] => 0.25
)
)
This is that array which I want to sort according to distance. eg, This should be look like this after sorting,
Array (
[0] => Array (
[teamid] => xyz
[distance] => 0.25
)
[1] => Array (
[teamid] => abc
[distance] => 1.25
)
)
If anyone know answer then please explain or suggest me link from where I can understand from beginning. Thank You.
Here is what you need to do.
$a = array(array( 'teamid' => 'abc', 'distance' => 1.25 ), array( 'teamid' => 'xyz', 'distance' => 0.25 ));
$distance = array();
foreach ($a as $key => $row)
{
$distance[$key] = $row['distance'];
}
array_multisort($distance, SORT_ASC, $a);
print_r($a);
This outputs
Array
(
[0] => Array
(
[teamid] => xyz
[distance] => 0.25
)
[1] => Array
(
[teamid] => abc
[distance] => 1.25
)
)
source Example #3 Sorting database results
DEMO
Edit
as per Mike's comment,
here are two answers,
one tells that on single array you should use usort(as Mike's answer) and array_multisort is used to compare elements from different arrays (or sub-arrays) at the same time.
in the other answer, as Mike wants some bench marking
usort() is more concise and doesn't require extracting a column array to feed to array_multisort(). (It also does less than array_multisort.)
However, when I repeatedly tested it today on arrays of 20,000 and
10,000 representative data rows, usort() was 7-15x slower than
array_multisort() when the column was random values of type int and
the column was pre-extracted. That is as one might expect, since for
every comparison you're comparing an entire php function call to
optimized intrinsic code.
more about bench marking notes, read full answer
$array = array(
array('teamid' => 'a', 'distance' => 1.25),
array('teamid' => 'b', 'distance' => 0.25),
array('teamid' => 'c', 'distance' => 2.5),
array('teamid' => 'd', 'distance' => 0.75),
);
function cmp($a, $b)
{
if ($a['distance'] == $b['distance']) return 0;
return ($a['distance'] < $b['distance']) ? -1 : 1;
}
usort($array, "cmp");
More info: http://php.net/usort
Related
I want to get the index of an array without foreach. this is sample array
Array
(
[0] => Array
(
[gcr_distance] => 31.0
[gcr_id] => 23
)
[1] => Array
(
[gcr_distance] => 28.0
[gcr_id] => 22
)
[2] => Array
(
[gcr_distance] => 26.0
[gcr_id] => 20
)
[3] => Array
(
[gcr_distance] => 110.0
[gcr_id] => 21
)
)
suppose if my data is gcr_id=21, by comparing with the above array it should give me an index of array 3
You can use a combination of array_search and array_column. array_column returns all the values which have a key of 'gcr_id' and then array_search returns the key which corresponds to a value of 21.
$array = array(
array('gcr_distance' => 31.0, 'gcr_id' => 23),
array('gcr_distance' => 28.0, 'gcr_id' => 22),
array('gcr_distance' => 26.0, 'gcr_id' => 20),
array('gcr_distance' => 110.0, 'gcr_id' => 21)
);
$key = array_search(21, array_column($array, 'gcr_id'));
echo $key;
Output:
3
Inspired by #Elementary's comment, I did some bench testing on this. What I found was that on a 100k entry array, array_search and array_column took around 80% of the time that a foreach based search took when the entry was not in the array, 95% of which was in the call to array_column. So it would seem that on average, a foreach based search would be faster.
There is the following array in my application:
array (
[item_name_1] => GTA V
[item_quantity_1] => 4
[item_price_1] => 5990
[item_name_2] => Watch_Dogs
[item_quantity_2] => 1
[item_price_2] => 5990
)
I want to divide/split this array into two pieces like that:
array (
[item_name_1] => GTA V
[item_quantity_1] => 4
[item_price_1] => 5990
)
array (
[item_name_2] => Watch_Dogs
[item_quantity_2] => 1
[item_price_2] => 5990
)
If you didn't realized, I want to separate items suffixed by 1 and 2 – and successively – unto different matrices and I really don't see the best way to perform this. Maybe regex?
I already tried to play with explode() and implode(), but no success – I have no creativity enough to explore their best.
<?php
$src = array (
'item_name_1' => 'GTA V',
'item_quantity_1' => 4,
'item_price_1' => 5990,
'item_name_2' => 'Watch_Dogs',
'item_quantity_2' => 1,
'item_price_2' => 5990,
);
$dest = array();
foreach($src as $k => $v) {
$sfx = preg_replace('/.*?_([0-9]+)$/', '$1',$k);
$dest[$sfx][$k] = $v;
}
print_r($dest);
Suppose I have a php array like this:
$shop = array( array("name"=>"Tom", "level"=> 1.25 ),
array("name"=>"Mike","level"=> 0.75 ),
array("name"=>"John","level"=> 1.15 )
);
I want to filter this array similar to filtering a mysql table with where conditions. Supposedly I want every array where level is higher than 1. I could iterate through and check with if statements. Are there any php solutions to this?
array_filter is what you are looking for:
$results= array_filter($shop, function($item) { return $item['level'] > 1; });
print_r($results);
Output:
Array
(
[0] => Array
(
[name] => Tom
[level] => 1.25
)
[2] => Array
(
[name] => John
[level] => 1.15
)
)
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do I sort a multidimensional array in php
Array ( [0] => Array (
[card_name] => CardA
[str] => 10
[def] => 10
[desc] => - Recover 150 points of vitality
- Attack twice"
[qty] => 5
)
[1] => Array (
[card_name] => CardD
[str] => 40
[def] => 40
[desc] => - Investigate enemy's weakpoint
[qty] => 3
)
[2] => Array ( [card_name] => CardG
[str] => 35
[def] => 20
[desc] =>
[qty] => 1
)
[3] => Array (
[card_name] => CardH
[str] => 25
[def] => 30
[desc] =>
[qty] => 1
)
[4] => Array (
[card_name] => CardI
[str] => 15
[def] => 40
[desc] => - Enhance strength
[qty] => 1
)
[5] => Array (
[card_name] => CardJ
[str] => 5
[def] => 50
[desc] => - Make silence
[qty] => 3
)
)
I have a simple question about sorting arrays. I just want to sort the array in either by str or def in either asc or desc. The examples in the php.net is a bit confusing and I was wondering if anyone can solve this small dilemma.
I know I should be using array_multi_sort for this.
Thanks.
Use the usort function. It will be something like this in your case :
function compare($valueA, $valueB) {
if ($valueA['str'] > $valueb['str']) {
return 1;
} else if ($valueA['str'] < $valueb['str']) {
return -1;
}
return 0;
}
usort($yourArray, "compare");
Try php usort - http://www.php.net/manual/en/function.usort.php
I've not tried and run the code but it'll be something below:
function cmp($a, $b)
{
return strcmp($a['def'],$b['def'])
}
$a = yourArray[];
usort($a, "cmp");
This will iterate through each element and pass the array element as a parameter and will use your custom function to sort.
usort() and strnatcmp() is your solution:
<?php
function build_sorter($key) {
return function ($a, $b) use ($key) {
return strnatcmp($a[$key], $b[$key]);
};
}
usort($array, build_sorter('def'));
print_r($array);
?>
It will sort all arrays by your defined key.
Array multisort requires you to build an array holding the values of the keys you want to sort by to do what you want, but with the same first dimension keys of the original array.
Thus if you make an array which holds 0 => 10, 1 => 5... etc where those are the values for str or def for keys 0 and 1, then you can do
foreach($originalArray as $key => $record) {
$keyValuesArray[$key] = $record['str'];
}
array_multisort($keyvaluesArray, SORT_ASC, $originalArray);
And original array would be modified to be sorted.
As for what you should be doing, I don't think array multisort is "the way" to do it, but is not a terrible way of doing it. Other solutions might be slightly more efficient.
I have the following multidimensional array:
Array
(
[0] => Array
(
[area] => 5
[estante] => 5
[anaquel] => 5
[no_caja] => 5
[id_tipo] => 3
[nombre_tipo] => Administrativo
)
[1] => Array
(
[area] => 5
[estante] => 5
[anaquel] => 5
[no_caja] => 5
[id_tipo] => 1
[nombre_tipo] => Copiador
)
[2] => Array
(
[area] => 5
[estante] => 5
[anaquel] => 5
[no_caja] => 5
[id_tipo] => 2
[nombre_tipo] => Judicial
)
)
and I want to reduce it by having all the different values (intersection) between them. The dimension of the array may change (I'm retrieving the info from a database). I have thought in using functions like array_reduce and array_intersect, but I have the problem that they work only with one-dimension arrays and I can't find the way to pass an indefinite (not previous known) number of parameters to these function. I'd like to have an output like this:
Array([0]=>Copiador, [1]=>Administrativo, [2]=>Judicial).
How can I do this?
Thanks in advance.
$arr=array(
array (
'area' => 5 ,
'estante' => 5 ,
'anaquel' => 5,
'no_caja' => 5,
'id_tipo' => 3,
'nombre_tipo' => 'Administrativo'),
array (//etc.
)
);
$fn=function(array $a, $k){
if(array_key_exists($k,$a)) return $a[$k];
};
$b=array_map($fn,$arr,array_fill(0,count($arr),'nombre_tipo'));
print_r($b);
/*
Array
(
[0] => Administrativo
[1] => Copiador
[2] => Judicial
)
*/
$reduced = array();
foreach ($oldarray as $value) {
$reduced[] = $value['nombre_tipo'];
}
Although, a better solution may be to just modify your SQL query so you get the correct data to begin with.
Note: you can also do it with array_reduce, but I personally prefer the method above.
$reduced = array_reduce($oldarray,
function($a, $b) { $a[] = $b['nombre_tipo']; return $a; },
array()
);
This task is exactly what array_column() is for -- extracting columnar data.
Call this:
var_export(array_column($your_array, 'nombre_tipo'));
This will output your desired three-element array. ...I don't understand the sorting in your desired output.
Seems like you want array_map
$newArr = array_map(function($a) {
return $a['nombre_tipo'];
}, $oldArr);
var_dump($newArr);