I'd like to pack a string consisting of a 64 bits, 32 bits and 32 bits ints.
I don't have much experience with the pack function (or bits altogether) so I'm trying to do something like this:
pack('JNN', 1, 2, 3);
// and
unpack('JNN');
But that does not yield the result I'm after.
The problem is that when I run that code I receive the following:
array [
"NN" => 1
]
But I expected this:
array [
1,
2,
3
]
Any idea how to approach this?
Thanks in advance,
pack creates a 16-character string.
$str = pack('JNN', 1, 2, 3);
//string(16) "\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x03"
unpack requires keys for the format elements. Example:
$arr = unpack('Jint64/N2int32_',$str);
/*
array (
'int64' => 1,
'int32_1' => 2,
'int32_2' => 3,
)
*/
For more examples, see Unpack in the PHP manual.
If purely numeric keys are required, the array_values function can be used.
Related
I need use yield and yield from at same function, but it seems not works as intended, once that it yields only the last yield from or yield (what comes last).
My code is (https://3v4l.org/jFDXh):
function yieldItems() {
yield 1;
yield 2;
yield 3;
yield from [4, 5, 6];
yield from [7, 8, 9];
}
var_dump(
iterator_to_array(
yieldItems()
)
);
For all PHP versions it will only outputs [ 7, 8, 9 ], but seems clear to me that it should be [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ] instead.
However, if I do the same through a foreach, everything seems normal. It looks like it is a problem related to iterator_to_array(), but in fact, I need to convert this Generator to an array.
So, what I am missing?
When I was concluding, I realized that the problem was really related to iterator_to_array(), so I decided to search more deeply in the PHP Documentation / Generators and it shows precisely this type of problem.
Following the documentation:
yield from does not reset the keys. It preserves the keys returned by the Traversable object, or array. Thus some values may share a common key with another yield or yield from, which, upon insertion into an array, will overwrite former values with that key.
A common case where this matters is iterator_to_array() returning a keyed array by default, leading to possibly unexpected results. iterator_to_array() has a second parameter use_keys which can be set to FALSE to collect all the values while ignoring the keys returned by the Generator.
What this means, in general, is that when using yield/yield from, it will outputs keys too (the first yield will be 0, for instance), just as it actually exists for pure arrays. So the code below will fail similarly (https://3v4l.org/pWeWT):
function willOutputSingle() {
yield 'sameKey' => 'originalValue';
yield 'sameKey' => 'otherValue';
}
var_dump(
iterator_to_array(
willOutputSingle()
)
);
// Outputs: [ 'sameKey' => 'otherValue' ]
It will happen because we yields to pairs like [ 'sameKey' => 'originalValue' ] and then [ 'sameKey' => 'otherValue' ], so when we converts it to array, via iterator_to_array() the results is basically that:
[ 'sameKey' => 'originalValue',
'sameKey' => 'otherValue ]
But how PHP does not allows identical keys, only the last one is preserved.
The solution to this is pass false as second argument to iterator_to_array(), because it will not preserve keys yielded, so result will be an zero-index array. The result will be:
[ 0 => 'originalValue',
1 => 'otherValue' ]
This question already has answers here:
Custom key-sort a flat associative based on another array
(16 answers)
Closed 2 years ago.
I have an associative array filled with more or less randomly mixed numeric and string keys, let's go with such example:
$arr = array('third'=>321, 4=>1, 65=>6, 'first'=>63, 5=>88, 'second'=>0);
Now I'd like to sort it in such way:
Sort the array so the numeric keys would be first, and string keys after.
The numeric values sholud be in specific order: 5, 4, 65
The string keys should be ordered by specific order as well: 'first', 'second', 'third'
Output in this case should look like: array(5=>88, 4=>1, 65=>6, 'first'=>63, 'second'=>0, 'third'=>321)
Each element might not be present at all in the original $arr, which might be additional problem...
My guess would be to split the array and make separate one with string keys, and one with numerc keys. Than sort each one and glue them together... But I do't know how to do it?
Edit: Turned out to be a very poor idea, much better approach is in the answer below.
The spaceship operator inside of a uksort() call is the only way that I would do this one.
Set up a two arrays containing your prioritized numeric and word values, then flip them so that they can be used a lookups whereby the respective values dictate the sorting order.
By writing two arrays of sorting criteria separated by <=> the rules will be respected from left to right.
The is_int() check is somewhat counterintuitive. Because we want true outcomes to come before false outcomes, I could have swapped $a and $b in the first element of the criteria arrays, but I decided to keep all of the variables in the same criteria array and just negate the boolean outcome. When sorting ASC, false comes before true because it is like 0 versus 1.
Code: (Demo)
$numericPriorities = array_flip([5, 4, 65]);
$numericOutlier = count($numericPriorities);
$wordPriorities = array_flip(['first', 'second', 'third']);
$wordOutlier = count($wordPriorities);
$arr = ['third' => 321, 4 => 1, 'zero' => 'last of words', 7 => 'last of nums', 65 => 6, 'first' => 63, 5 => 88, 'second' => 0];
uksort(
$arr,
function($a, $b) use ($numericPriorities, $numericOutlier, $wordPriorities, $wordOutlier) {
return [!is_int($a), $numericPriorities[$a] ?? $numericOutlier, $wordPriorities[$a] ?? $wordOutlier]
<=>
[!is_int($b), $numericPriorities[$b] ?? $numericOutlier, $wordPriorities[$b] ?? $wordOutlier];
}
);
var_export($arr);
or (demo)
uksort(
$arr,
function($a, $b) use ($numericPriorities, $numericOutlier, $wordPriorities, $wordOutlier) {
return !is_int($a) <=> !is_int($b)
?: (($numericPriorities[$a] ?? $numericOutlier) <=> ($numericPriorities[$b] ?? $numericOutlier))
?: (($wordPriorities[$a] ?? $wordOutlier) <=> ($wordPriorities[$b] ?? $wordOutlier));
}
);
Output:
array (
5 => 88,
4 => 1,
65 => 6,
7 => 'last of nums',
'first' => 63,
'second' => 0,
'third' => 321,
'zero' => 'last of words',
)
I was extreamly overthinking the case. I came out with a solution that I was unalbe to implement, and unnecessary I described it and ask for help on how to do this.
Turned out that what I really wanted was extreamly simple:
$arr = array('third'=>321, 4=>1, 65=>6, 'first'=>63, 5=>88, 'second'=>0);
$proper_order = array(5, 4, 65, 'first', 'second', 'third');
$newtable = array();
foreach ($proper_order as $order)
{
if (isset($arr[$order]))
$newtable[$order] = $arr[$order];
}
unset($order, $arr, $proper_order);
print_r($newtable);
The result is as expected, and the code should resist the case when the original $arr is incomplete:
Array
(
[5] => 88
[4] => 1
[65] => 6
[first] => 63
[second] => 0
[third] => 321
)
Let's say I've got an Articles collection, and I want to fetch the popular articles.
So first, I make a scopePopular() method in the Article method. Very simple.
Now I want to fetch their ids, so I'll do this:
Article::popular->pluck('id');
The result will be an associative array:
[
0 => 1,
1 => 34,
2 => 17
...
];
I want to get a normal array, without the keys, Like:
[1, 34, 17]
I know I can just do something like this:
array_values(Article::popular->pluck('id'));
But I believe Laravel has much more cleaner way to do this. Any ideas?
All arrays have indexes.
[
0 => 1,
1 => 34,
2 => 17
];
equals to
[1, 34, 17]
In other words:
$a1 = [0 => 1, 1 => 34, 2 => 17];
$a2 = [1, 34, 17];
$a1 === $a2;
// returns True
You can use values() method which is wrapper for array_values():
Article::popular->pluck('id')->values();
Its exactly what you need and what you get, By default php has the incremental key from 0.
You want to see something like a JSON array I assume.
Just do a return the array and you will see the JSOn array in browser, but internally its like this only.
Please confirm and let me know.Thanks
$store_type = \App\Websites::find($request->store_id)->first()->store_type;
// Outputs - just a string like "live" // there was option like a demo, live, staging ...
It might be useful for someone else.
I can define an array in PHP like this:
$array = array();
In C++, we have two kinds of array.
The first kind is a fixed size array, for example:
int arr[4]; // 4 ints, hardcoded size
The second kind is a dynamic sized array
std::vector<int> v; // can grow and shrink at runtime
What kind of array does PHP use? Are both kinds of arrays in PHP? If so, can you give me examples?
PHP is not as strict as C or C++. In PHP you don't need to specify the type of data to be placed in an array, you don't need to specify the array size either.
If you need to declare an array of integers in C++ you can do it like this:
int array[6];
This array is now bound to only contain integers. In PHP an array can contain just about everything:
$arr = array();
$arr[] = 1;
$arr[] = 2;
$arr[] = 3;
$arr[] = 4;
var_dump($arr); //Prints [1,2,3,4]
$arr[] = 'hello world'; //Adding a string. Completely valid code
$arr[] = 3.14; //Adding a float. This one is valid too
$arr[] = array(
'id' => 128,
'firstName' => 'John'
'lastName' => 'Doe'
); //Adding an associative array, also valid code
var_dump($arr); //prints [1,2,3,4,'hello world',3.14, [ id => 128, firstName => 'John', lastName => 'Doe']]
If you're coming from a C++ background it's best to view the PHP array as a generic vector that can store everything.
From php.net
An array in PHP is actually an ordered map. A map is a type that
associates values to keys. This type is optimized for several
different uses; it can be treated as an array, list (vector), hash
table (an implementation of a map), dictionary, collection, stack,
queue, and probably more. As array values can be other arrays, trees
and multidimensional arrays are also possible.
Basically there are three Usage patterns of array in PHP.
Indexed array: Arrays with sequential numeric index, such as 0, 1, 2, etc. Example:
$myarray = array();
$myarray[0] = "test data 1";
$myarray[1] = "test data 2";
$myarray[3] = "test data 3";
Associative array: This is the most frequently used type of PHP arrays whose elements are defined in key/value pair. Example:
$myarray = array();
$myarray["key1"] = "value 1";
$myarray["key2"] = "value 2";
$myarray["key3"] = "value 3";
Multidimensional array: Arrays whose elements may contains one or more arrays. There is no limit in the level of dimensions. Example:
$myarray = array();
$myarray[0] = array("data01","data02","data03");
$myarray[1] = array("data11","data12","data13");
For more details - Refer to PHP 5 Arrays.
PHP uses three kinds of array:
Numeric array − An array with a numeric index. Values are stored and accessed in linear fashion.
Associative array − An array with strings as index. This stores element values in association with key values rather than in a strict linear index order.
Multidimensional array − An array containing one or more arrays and values are accessed using multiple indices.
Numeric Array Ex:
$numbers = array( 1, 2, 3, 4, 5);
Associative Array Ex:
$salaries = array("mohammad" => 2000, "qadir" => 1000, "zara" => 500);
Multidimensional Array Ex:
$marks = array(
"mohammad" => array (
"physics" => 35,
"maths" => 30,
"chemistry" => 39
),
"qadir" => array (
"physics" => 30,
"maths" => 32,
"chemistry" => 29
),
"zara" => array (
"physics" => 31,
"maths" => 22,
"chemistry" => 39
)
);
A php array, in C++ terms, is roughly:
std::map< std::experimental::any, std::experimental::any >
where std::experimental::any is a type that can hold basically anything. The php equivalent also can be sorted with the equivalent of <.
Well not quite -- closer to the truth is that a php array is an abstract interface that exposes much of the operations that the above map would provide in C++ (the C++ map is a concrete implementation).
Arrays with contiguous numeric keys stored in the Variant are treated much like a std::vector<Variant>, and under the interface the php system might even use vector<Variant> or something similar to store it, or even have two different internal details, one of which is for contiguous blocks of integer indexed data, and the other for sparse entries. (I don't know how php is implemented, but that is how I would do it)
PHP uses numeric, associative arrays, and multidimensional arrays. Arrays are dynamic in nature, and no size should be mentioned. Go through php.net/manual/en/language.types.array.php to find details.
Here's what I am trying to accomplish:
function foo($args) {
switch($args['type']) {
case 'bar':
bar($args['data']); // do something
break;
}
}
// or something like that
Which is basically a way of using named parameters in PHP.
Now, in order to build this $args array, I am forced to write ugly syntax like:
$builtArgs = array('type' => 'bar',
'data' => array(1, 2, 3),
'data2' => array(5, 10, 20)
);
foo($builtArgs);
Which gets uglier as I add more dimensions to the array, and also forces me to write tons of array(...) constructs. Is there a prettier way to do this?
For one thing, it could be done if we could use Python-like syntax:
$buildArgs = {'type' : 'bar', 'data' : [1, 2, 3], 'data2' : [5, 10, 20]};
But it is PHP.
You could create a JSON-encoded string and use json_decode() to convert it into a variable. This has syntax very similar to the Python-like syntax you mentioned.
$argstr = '{"type" : "bar", "data" : [1, 2, 3], "data2" : [5, 10, 20]}';
$buildArgs = json_decode($argstr, true);
EDIT: Updated code to accommodate #therefromhere's suggestion.
No. Alternative syntaxes for creating arrays have been proposed several times (the link lists 5 separate threads in the dev mailing list), but they were rejected.
No, there is no "short-syntax" to write arrays nor objects, in PHP : you have to write all those array().
(At least, there is no such syntax... yet ; might come in a future version of PHP ; who knows ^^ )
But note that have too many imbricated arrays like that will makes things harder for people who will have to call your functions : using real-parameters means auto-completion and type-hinting in the IDE...
There are no alternatives to constructing these nested arrays-- but there are options in how you can format your code that makes it readable. This is strictly preference:
return array
(
'text' => array
(
'name' => 'this is the second',
'this' => 'this is the third',
'newarr' => array
(
'example'
),
)
);
// Or using the long way
$array = array();
$array += array
(
'this' => 'is the first array'
);