order a php array by a sub string - php

I have an array:
Array
(
[0] => 20140929102023_taxonomies.zip
[1] => 20140915175317_taxonomies.zip
[2] => 20140804112307_taxonomies.zip
[3] => 20141002162349_taxonomies.zip
)
I'd like order this array by first 14 characters of strings, that represents a date.
I'd like an array like this:
Array
(
[0] => 20140804112307_taxonomies.zip
[1] => 20140915175317_taxonomies.zip
[2] => 20140929102023_taxonomies.zip
[3] => 20141002162349_taxonomies.zip
)
Thanks.

The sort() function with the natural sorting algorithm should give you the result you are looking for. It's as simple as this.
sort($array, SORT_NATURAL);
This will updat the existing $array variable, you do not need to store the return of the sort function. It simply returns true or falseon success and failure.
The sort function will update the keys as well, if for some reason you need to maintain the keys, and just update the order, you can use asort().
asort($array, SORT_NATURAL);
PHP has tons of ways to sort arrays, you can find the manual for that here.

There is no need to use natural sorting algorithms. A normal sort() would produce the effect you desire, as it will compare each string "starting from the left". For example "20141002162349_taxonomies.zip" is bigger than "20140929102023_taxonomies" because the fifth character (the first digit of the month) is 1 in the first and 0 in the second (and 1 > 0, even in a string - comparison works with ASCII code points).
So:
<?php
$array = array('20141002162349_taxonomies.zip', '20140929102023_taxonomies.zip', '20140804112307_taxonomies.zip', '20140915175317_taxonomies.zip');
sort($array);
var_dump($array);
Result:
array(4) {
[0]=>
string(29) "20140804112307_taxonomies.zip"
[1]=>
string(29) "20140915175317_taxonomies.zip"
[2]=>
string(29) "20140929102023_taxonomies.zip"
[3]=>
string(29) "20141002162349_taxonomies.zip"
}

Related

PHP - Why doesn't array_multisort function sort correctly?

please view the following code with 2 arrays. i use multisort function with sort flags for ascending and numeric then display. as you can see in the output that array 2 starts with 100 when it should be last. please explain what is causing this and how to sort it correctly. thank you.
<?php
$array1 = array(1,7,10,6);
$array2 = array(100,20,25,10);
array_multisort($array1, SORT_ASC, SORT_NUMERIC, $array2);
print_r($array1);
echo "<br>";
print_r($array2);
?>
output:
Array ( [0] => 1 [1] => 6 [2] => 7 [3] => 10 )
Array ( [0] => 100 [1] => 10 [2] => 20 [3] => 25 )
Ah, yes, array_multisort is a bit tricky to understand the first time round.
Basically the sort is lexicographical, a fancy word meaning that the first array is sorted and the second arrays elements are ordered according to the first array.
Look at your first (output) array and see the order and map it to the initial second array and you'll see whats happening.
So the second array you take the 1st, 4th , 2nd and 3rd elements.
If you just want plain sorting for multiple arrays then just do them one by one or over a loop.

How does one split a string on two delimeters into an associative array

The answer on this question, pointed me in a possible direction, but it processes the string once, then loops through the result. Is there a way to do it in one process?
My string is like this, but much longer:
954_adhesives
7_air fresheners
25_albums
236_stuffed_animial
819_antenna toppers
69_appliances
47_aprons
28_armbands
I'd like to split it on linebreaks, then on underscore so that the number before the underscore is the key and the phrase after the underscore is the value.
Just use a regular expression and array_combine:
preg_match_all('/^([0-9]+)_(.*)$/m', $input, $matches);
$result = array_combine($matches[1], array_map('trim', $matches[2]));
Sample output:
array(8) {
[954]=>
string(9) "adhesives"
[7]=>
string(14) "air fresheners"
[25]=>
string(6) "albums"
[236]=>
string(15) "stuffed_animial"
[819]=>
string(15) "antenna toppers"
[69]=>
string(10) "appliances"
[47]=>
string(6) "aprons"
[28]=>
string(8) "armbands"
}
Use ksort or arsort if you need the result sorted as well, by keys or values respectively.
You can do it in one line:
$result = preg_split('_|\n',$string);
Here is a handy-dandy tester: http://www.fullonrobotchubby.co.uk/random/preg_tester/preg_tester.php
EDIT:
For posterity, here's my solution. However, #Niels Keurentjes answer is more appropriate, as it matches a number at the beginning.
If you wanted to do this with regular expressions, you could do something like:
preg_match_all("/^(.*?)_(.*)$/m", $content, $matches);
Should do the trick.
If you want the result to be a nested array like this;
Array
(
[0] => Array
(
[0] => 954
[1] => adhesives
)
[1] => Array
(
[0] => 7
[1] => air fresheners
)
[2] => Array
(
[0] => 25
[1] => albums
)
)
then you could use an array_map eg;
$str =
"954_adhesives
7_air fresheners
25_albums";
$arr = array_map(
function($s) {return explode('_', $s);},
explode("\n", $str)
);
print_r($arr);
I've just used the first three lines of your string for brevity but the same function works ok on the whole string.

How does PHP set keys for arrays?

I have an array:
$a = array('color' => 'green', 'format' => 'text', 'link_url');
and another:
$b = array('zero', 'one', 'two', 'three', 'test' => 'ok', 'four');
And with array_merge() I have an array like this:
Array
(
[color] => green
[format] => text
[0] => link_url
[1] => zero
[2] => one
[3] => two
[4] => three
[test] => ok
[5] => four
)
Why PHP sets array key as above? Why not like this:
Array
(
[color] => green
[format] => text
[2] => link_url
[3] => zero
[4] => one
[5] => two
[6] => three
[test] => ok
[8] => four
)
That's because numeric IDs are counted separately from seeing indices. The string indices have no number and are not counted.
Quoting from the PHP manual for your original array definitions:
The key is optional. If it is not specified, PHP will use the increment of the largest previously used integer key.
and from the docs on array_merge():
If the input arrays have the same string keys, then the later value for that key will overwrite the previous one. If, however, the arrays contain numeric keys, the later value will not overwrite the original value, but will be appended.
Values in the input array with numeric keys will be renumbered with incrementing keys starting from zero in the result array.
So it's all quite explicitly documented
Well, if you look at the original array, should be clear:
array(3) {
["color"]=>
string(5) "green"
["format"]=>
string(4) "text"
[0]=>
string(8) "link_url"
}
You appear to have assumed an ordering or a congruity with non-numeric keys, which does not exist.
The numeric keys have an order and this is represented in their new values; the string keys are not part of that ordering system and thus do not affect those new numeric values.
This is simply the way it is and it makes complete sense.
Please check the doc :
If the input arrays have the same string keys, then the later value for that key will overwrite the previous one. If, however, the arrays contain numeric keys, the later value will not overwrite the original value, but will be appended.
Values in the input array with numeric keys will be renumbered with incrementing keys starting from zero in the result array.
Ref: http://www.php.net/manual/en/function.array-merge.php

How to combine an array with another array

I've two arrays array1 and array2 and I want to add all elements of array2 to the end of array1. array1 contains many items.
The keys are numeric and I don't want this syntax:
array1 = array1 + array2
or
array1 = SomeArrayFun(array1,array2)
As it takes away CPU times ( as array is created twice )
What I want is:
array1 . SomeAddFun(array2); // This will not create any new arrays
Is there any way to do it?
If you'd like to append data to an existing array you should se array_splice.
With the proper arguments you'll be able to insert/append the contents of $array2 into $array1, as in the below example.
$array1 = array (1,2,3);
$array2 = array (4,5,6);
array_splice ($array1, count ($array1), 0, $array2);
print_r ($array1);
output:
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
[5] => 6
)
You might use ArrayObject with the append function:
$arrayobj = new ArrayObject(array('first','second','third'));
$arrayobj->append('fourth');
Result:
object(ArrayObject)#1 (5) {
[0]=>
string(5) "first"
[1]=>
string(6) "second"
[2]=>
string(5) "third"
[3]=>
string(6) "fourth"
}
Don't know for appending arrays though, as they seem to be appended as a "subarray" and not as part of the whole.
Docs: http://www.php.net/manual/en/arrayobject.append.php

Difference between var_dump,var_export & print_r

What is the difference between var_dump, var_export and print_r ?
var_dump is for debugging purposes. var_dump always prints the result.
// var_dump(array('', false, 42, array('42')));
array(4) {
[0]=> string(0) ""
[1]=> bool(false)
[2]=> int(42)
[3]=> array(1) {[0]=>string(2) "42")}
}
print_r is for debugging purposes, too, but does not include the member's type. It's a good idea to use if you know the types of elements in your array, but can be misleading otherwise. print_r by default prints the result, but allows returning as string instead by using the optional $return parameter.
Array (
[0] =>
[1] =>
[2] => 42
[3] => Array ([0] => 42)
)
var_export prints valid php code. Useful if you calculated some values and want the results as a constant in another script. Note that var_export can not handle reference cycles/recursive arrays, whereas var_dump and print_r check for these. var_export by default prints the result, but allows returning as string instead by using the optional $return parameter.
array (
0 => '',
1 => false,
2 => 42,
3 => array (0 => '42',),
)
Personally, I think var_export is the best compromise of concise and precise.
var_dump and var_export relate like this (from the manual)
var_export() gets structured
information about the given variable.
It is similar to var_dump() with one
exception: the returned representation
is valid PHP code.
They differ from print_r that var_dump exports more information, like the datatype and the size of the elements.

Categories