So I have a very big JSON string that represents a multidimensional array with 255 entries, each entry, being an array with 255 other entries, liek this:
0 => array(0, 1, ..., 255),
1 => array(0, 1, ..., 255),
...
255 => array(0, 1, ..., 255),
(the only difference is that the values from the 2nd level are strings made out of 2-3 characters in my case)
Could I retrieve a certain value from this encoded string based on a key, but without actually decoding it to an array?
for example, I may want to get $arr[37][78];
To do this currently I'd have to:
$arr = json_decode($string);
$value = $arr[37][78];
Which I'd like to avoid because the decoded string takes a huge amount of memory as an array...
No, not based on a key. Since at the point that you receive it it's a string, your only option is regex or substr(), using indexes.
Related
I have an array that i need to pack with python to 16bit depth with
I have been doing this with php without any issues.
Array is just just large set of numbers like this - [1, 2, 3, 4, 5, 700, 540...]
With php I do this process in one line:
$encoded_string = pack("s*", ...$array); // Done
I can not for the love of god figure out how same can be done in python
I have read the documentation, I looked at examples and I can not get this done
Best I have is below and it does not work in any variation i have tried.
encoded_string = struct.pack('h', *array)
You have to call struct.pack on each member of your array:
import struct
nums = [1, 2, 3, 4, 5, 700, 540]
as_bytes = [struct.pack('h', i) for i in nums]
# Produces
[b'\x01\x00', b'\x02\x00', b'\x03\x00', b'\x04\x00', b'\x05\x00', b'\xbc\x02', b'\x1c\x02', b'\x08\x00']
and then that you can join into a single byte string if you want:
>>> b''.join(as_bytes)
b'\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\xbc\x02\x1c\x02'
Note: you can also use the endianness modifiers to specify the alignment for the output bytes.
Edit: #Proper reminded me that struct.pack's formatting also supports specifying the number of target packed types, so this can be done more easily by including the data length in an f-string with the format specifier:
>>> struct.pack(f'{len(data)}h', *data)
b'\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\xbc\x02\x1c\x02'
Thank you for the reply b_c to be honest I hate python with a passion at this point, there was another problem that i had to fix, the array was created as str and not int after it was "exploded". So it had to be remapped to int.
Your code does work, thank you.
There is a way to do it with my initial code, however you have to define number of values you want to process. It is possible to simply count number of values in the array and add than in to make it automated
data_array = map(int,data) # converts all values in the array to int
encoded_string = struct.pack('240s',*data_array) # 240 is number of values in the array
I'm using imagefilledrectangle() in my project. The 2nd, 3rd, 4th and 5th parameters accept point coordinates. The function description specifies the type of these should be integer. My problem is, I'm calculating these at run time and ensuring they are integers is proving difficult.
My question:
What are the consequences of using 'real numbers' instead of integers? For example:
imagefilledrectangle( $img, 1.2, 3.4, 4.5, 7.8, $color )
Ref: http://php.net/manual/en/function.imagefilledrectangle.php
As written, your floats will get integerized by truncation, as per PHP's float->int conversion rules. So the function call will effectively be
imagefilledrectangle( $img, 1, 3, 4, 7, $color )
due to the function explicitly defining the position arguments as being int.
e.g.
echo (int)7.8; // outputs '7'
echo (int)1.2; // outputs '1'
Does PHP have an Ordered Dictionary, like that in Python? IE, each key value pair additionally has an ordinal associated with it.
That's how PHP arrays work out of the box. Each key/value pair has an ordinal number, so the insertion order is remembered. You can easily test it yourself:
http://ideone.com/sXfeI
If I understand the description in the python docs correctly, then yes.
PHP Arrays are actually only ordered maps:
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.
PHP Array docs
PHP arrays work this way by default.
$arr = array('one' => 1, 'two' => 2, 'three' => 3, 'four' => 4);
var_dump($arr); // 1, 2, 3, 4
unset($arr['three']);
var_dump($arr); // 1, 2, 4
$arr['five'] = 5;
var_dump($arr); // 1, 2, 4, 5
$array = array(
'first element',
'second element',
'third element',
);
echo $array['1'];
echo $array[1];
They both produce the same result.
I am asking this question because I noticed for example drupal accesses the index as string literals, where as php.net uses integers.
Are there advantages of one over the other?
Of course I know why $array[foo] is bad.
It's indifferent in terms of semantics.
When you do $array['string'] and 'string' is a number in base 10 without leading zeros and decimal point that fits on the integer range (i.e., is between -PHP_INT_MAX-1 and PHP_INT_MAX), it will be converted into an integer.
In terms of performance, it's preferrable to use an integer directly because that will skip the conversion step.
PHP will just coerce the '1' to an integer, or array key 0x01.
In theory, it would be faster to just access the keys, if they're just a simple array like the one you have posted, with their integer values.
The two forms are identical to the point that one will overwrite the other if they are used to assign values... for example:
<?php
$new = array(1 => "number", "1" => "string");
echo count($new); // <== Output: 1
echo "The array has {$new[1]} and {$new['1']}";
//Output: The array has string and string
?>
Live example
Theoretically the one where the server does less work is faster. Since no type coercion is necessary with $array[1], that's faster.
I am after a function which will let me sort a bunch of filenames over 4 arrays.
However, the a file must always end up in the same array - even if the number of files change.
Eg if I have files
myfile.html
anotherfile.html
morefiles.html
test.html
and my arrays
array1, array2, array3, array4
If I run this function then
array1 might get myfile.html and anotherfile.html
If I run it again and add some more files (or less files, like not pass anotherfile.html) then I would still expect array1 to get myfile.html
So just need some way to hash the filename which I can then use to point to a certain array, so not a random or one that checks how many files are in each array needs to be consistent.
There are many different ways to solve a task like this, what is below is a very basic introduction to the topic. If it is useful, great otherwise I hope it at least gives an idea what where you might want to go (or not!).
This example simple takes a hash of the filename (in this case MD5 just because you're probably familiar with it). The sscanf just gets the first character of the hash and turns it into a number between 0 and 15 (since md5() returns a hexadecimal number). Since we only want to distribute between four arrays, the modulus operator (%) is used so that $num will always result in 0, 1, 2 or 3 which is then used as an array key (c.f. your $array1, $array2, etc.).
$files = array('a.html','b.html','c.html','d.html');
$arrays = 4;
$array = array_fill(0, $arrays, array());
// For each file name put it into the appropriate slot in $array
foreach ($files as $filename) {
sscanf(md5($filename), '%1x', $hex);
$key = $hex % $arrays;
$array[$key][] = $filename;
}
// See what happened
var_dump($array);
For this particular example, the resulting array (which you can push into your separate variables if you like) has the following structure:
$array = array(
0 => array()
1 => array('c.html')
2 => array('d.html')
3 => array('a.html', 'b.html')
);