I have this array:
$array = array(
['name' => 'Indor Swimming Pool'],
['name' => 'abracadabra'],
);
I want sort if alphabetically, so I did:
usort($array, function($a, $b)
{
return strcmp($a['name'], $b['name']);
});
but when I dump it:
var_dump($array);
I get:
array(2) {
[0]=>
array(1) {
["name"]=>
string(19) "Indor Swimming Pool"
}
[1]=>
array(1) {
["name"]=>
string(11) "abracadabra"
}
}
this is incorrect, abracadabra should go as first
According to the ASCII table chr I comes first and then comes the a chr
ASCII Table
So here your array is actually getting sorted alphabetically to achieve the desired result you need to sort the array in the descending order
<?php
$data = array(
['name' => 'Indor Swimming Pool'],
['name' => 'abracadabra'],
);
arsort($data);
?>
Output
Array
(
[1] => Array
(
[name] => abracadabra
)
[0] => Array
(
[name] => Indor Swimming Pool
)
)
It works as intended. The reason for this order is that 'a' is actually after 'I' in ASCII.
Related
Supposed I have an array of
array(8) {
[0] =>
array(1) {
'Peter' =>
int(4)
}
[1] =>
array(1) {
'Piper' =>
int(4)
}
[2] =>
array(1) {
'picked' =>
int(4)
}
[3] =>
array(1) {
'peck' =>
int(4)
}
[4] =>
array(1) {
'pickled' =>
int(4)
}
How can I sort this multidimentional array by key example (Peter). I tried using
ksort($arr);
but it just return a boolean
The output that I want
array(8) {
[0] =>
array(1) {
'peck' =>
int(4)
}
[1] =>
array(1) {
'Peter' =>
int(4)
}
[2] =>
array(1) {
'picked' =>
int(4)
}
[3] =>
array(1) {
'pickled' =>
int(4)
}
[4] =>
array(1) {
'piper' =>
int(4)
}
the array should be sorted by key and in ascending order.
Sort with usort like this, check the demo
usort($array,function($a,$b){
return strcmp(strtolower(key($a)),strtolower(key($b)));
});
The ksort() method does an in-place sort. So while it only returns a boolean (as you correctly state), it mutates the values inside $arr to be in the sorted order. Note that based on your expected output, it looks like you want to do a case insensitive search. For that, you need to use the SORT_FLAG_CASE sort flag. So, instead of calling ksort($arr), you instead want to use ksort($arr, SORT_FLAG_CASE). You can see how ksort() uses sort flags, in the sort() method's documentation. Hope that helps!
You can do something like this,
$temp = array_map(function($a){
return key($a); // fetching all the keys
}, $arr);
natcasesort($temp); // sorting values case insensitive
$result = [];
// logic of sorting by other array
foreach($temp as $v){
foreach($arr as $v1){
if($v == key($v1)){
$result[] = $v1;
break;
}
}
}
Demo
Output
Array
(
[0] => Array
(
[peck] => 4
)
[1] => Array
(
[Peter] => 4
)
[2] => Array
(
[picked] => 4
)
[3] => Array
(
[pickled] => 4
)
[4] => Array
(
[Piper] => 4
)
)
I am trying to sort an array based on the first [0] child element. But in my code the keys are being replaced by the array number in the sort:
$myArray = array(
'my last row' => array(
'0' => 'ZZZZ',
'1' => 'AAAA'
),
'the first row' => array(
'0' => 'AAAA'
)
);
usort($myArray, 'cmp' ) ;
var_dump($myArray);
function cmp ($a, $b) {
return ( ( $a[0] > $b[0] ) ? 1 : -1 );
}
result:
array(2) {
[0]=> // should be ['the first row'] *not* [0]
array(1) {
[0]=>
string(4) "AAAA"
}
[1]=> // should be ['my last row'] *not* [1]
array(2) {
[0]=>
string(4) "ZZZZ"
[1]=>
string(4) "AAAA"
}
}
The sort order itself appears to be working as expected.
I would like to see the following:
the first row => AAAA
my last row => ZZZZ, AAAA
This is probably a very simple issue, but I cannot resolve it.
Thank you very much.
EDIT: this sort does not involve the key itself, but rather a child-element key. i believe that makes this question unique.
Try this:
It will maintain your index associations.
$myArray = array(
'my last row' => array(
'0' => 'ZZZZ',
'1' => 'AAAA'
),
'the first row' => array(
'0' => 'AAAA'
)
);
asort($myArray);
print_r($myArray);
Array ( [the first row] => Array ( [0] => AAAA ) [my last row] => Array ( [0] => ZZZZ [1] => AAAA ) )
Basically, I want to convert the below multidimensional array:
Array
(
[0] => Array
(
[0] => foo
[1] => bar
[2] => hello
)
[1] => Array
(
[0] => world
[1] => love
)
[2] => Array
(
[0] => stack
[1] => overflow
[2] => yep
[3] => man
)
)
Into this:
Array
(
[0] => foo
[1] => world
[2] => stack
[3] => bar
[4] => love
[5] => overflow
[6] => hello
[7] => yep
[8] => man
)
first element from first sub-array
first element from second sub-array, etc
second element from first sub-array
second element from second sub-array, etc...
So I've had a couple beers and I'll try and tighten this up later, but this does the trick for integer indexed arrays:
$result = array();
for($i=0; $c=array_column($array, $i); $i++) {
$result = array_merge($result, $c);
}
print_r($result);
Loop getting an array of columns starting with column 0 and increment the column number.
So long as there are columns, get an array of that column and merge with the result.
There is an often overlooked Iterator that will help you here: The MultipleIterator.
I have created some demo code: https://3v4l.org/beOMV
<?php
$arr = [
0 => [
0 => 'foo',
1 => 'bar',
2 => 'hello',
],
1 => [
0 => 'world',
1 => 'love',
],
2 => [
0 => 'stack',
1 => 'overflow',
2 => 'yep',
3 => 'man',
]
];
$parallelIterator = new MultipleIterator(MultipleIterator::MIT_NEED_ANY|MultipleIterator::MIT_KEYS_NUMERIC);
$parallelIterator->attachIterator(new ArrayIterator($arr[0]));
$parallelIterator->attachIterator(new ArrayIterator($arr[1]));
$parallelIterator->attachIterator(new ArrayIterator($arr[2]));
$result = [];
foreach ($parallelIterator as $values) {
foreach ($values as $value) {
if ($value !== null) {
$result[] = $value;
}
}
}
var_dump($result);
Essentially, iterating over the MultipleIterator will give you an array with all the first entries (and then second and so on) of ALL attached iterators in parallel. By using either MultipleIterator::MIT_NEED_ANY or MultipleIterator::MIT_NEED_ALL you can decide that the loop should stop either when the last iterator has no more elements, or when the first iterator runs out of elements. When you run until the last element of the last iterator, you'll get NULL instead.
When attaching iterators, you can also add a key that will be used in the array when iterating, and have to uses MultipleIterator::MIT_KEYS_ASSOC - I have simply used numeric indices here because the source of the particular array was not interesting.
The result is
array(9) {
[0]=> string(3) "foo"
[1]=> string(5) "world"
[2]=> string(5) "stack"
[3]=> string(3) "bar"
[4]=> string(4) "love"
[5]=> string(8) "overflow"
[6]=> string(5) "hello"
[7]=> string(3) "yep"
[8]=> string(3) "man"
}
Yes, you can iterate over that initial array when attaching the sub arrays to the MultipleIterator if you want:
foreach ($arr as $innerArr) {
$parallelIterator->attachIterator(new ArrayIterator($innerArr));
}
I promise you I've had a look at the many existing SO Qs about PHP sorting, including this mega one
I've got a PHP associative array, with strings as keys. Each value is an array of integers. I want to sort each array of integers, in simple ascending numerical order. I'm convinced this should be easy, and I've found enough examples that I think I should be doing the right thing, but it's not quite working, so there's a typo or I'm an idiot or something...
PHP:
//Each fruit corresponds to an array (series) of integers
$data = [
'banana' => [
1,3,2
],
'orange' => [
5,1,3
]
];
echo "Before sort:\n";
var_dump($data);
//For each fruit, I want to order the numbers
foreach ($data as $key => $series)
{
//Sort array of integers
sort($series);
//NB I wasn't sure about value/reference details of foreach loops, so I also tried
//retrieving a series into a variable, sorting, and then reassigning back to the same key
}
echo "\n\nAfter sort:\n";
var_dump($data);
Output:
Before sort:
array(2) {
'banana' =>
array(3) {
[0] =>
int(1)
[1] =>
int(3)
[2] =>
int(2)
}
'orange' =>
array(3) {
[0] =>
int(5)
[1] =>
int(1)
[2] =>
int(3)
}
}
After sort:
array(2) {
'banana' =>
array(3) {
[0] =>
int(1)
[1] =>
int(3)
[2] =>
int(2)
}
'orange' =>
array(3) {
[0] =>
int(5)
[1] =>
int(1)
[2] =>
int(3)
}
}
As you can see, in the output the inner arrays of integers have not been sorted. What am I doing wrong? (PHP 5.5.9, Windows 7)
Use a reference &:
foreach ($data as $key => &$series)
{
//Sort array of integers
sort($series);
// OR
// sort($data[$key]);
}
I have an array of objects, but I need to remove a similar objects by a few properties from them:
for example:
array(12) {
[0]=>
object(stdClass)#848 (5) {
["variant"]=>
object(stdClass)#849 (4) {
["name"]=>
string(8) "Alex"
}
["age"]=>
int(10)
}
[1]=>
object(stdClass)#851 (5) {
["variant"]=>
object(stdClass)#852 (4) {
["name"]=>
string(8) "Alex"
}
["age"]=>
int(10)
}
How to make a one object in array for this ( if for example I need to compare only by a name property? )
Still have an issue with it.
Updated
I've create a new array of objects:
$objects = array(
(object)array('name'=>'Stiven','age'=>25,'variant'=>(object)array('surname'=>'Sigal')),
(object)array('name'=>'Michael','age'=>30,'variant'=>(object)array('surname'=>'Jackson')),
(object)array('name'=>'Brad','age'=>35,'variant'=>(object)array('surname'=>'Pit')),
(object)array('name'=>'Jolie','age'=>35,'variant'=>(object)array('surname'=>'Pit')),
);
echo "<pre>";
print_r($objects);
So what I need to do is to compare an object properties (variant->surnames and ages), if two objects has a similar age and variant->surname we need to remove the one of these objects.
A half of solution is:
$tmp = array();
foreach ($objects as $item=>$object)
{
$tmp[$object->variant->surname][$object->age] = $object;
}
print_r($tmp);
Unfortunatelly I need an old-style array of objects.
I've found an example.
<?php
$a = array (
0 => array ( 'value' => 'America', ),
1 => array ( 'value' => 'England', ),
2 => array ( 'value' => 'Australia', ),
3 => array ( 'value' => 'America', ),
4 => array ( 'value' => 'England', ),
5 => array ( 'value' => 'Canada', ),
);
$tmp = array ();
foreach ($a as $row)
if (!in_array($row,$tmp)) array_push($tmp,$row);
print_r ($tmp);
?>
Quoted from here