Asked  2 Years ago    Answers:  5   Viewed   47 times

I've got a multidimensional associative array which includes an elements like

$data["status"]
$data["response"]["url"]
$data["entry"]["0"]["text"]

I've got a strings like:

$string = 'data["status"]';
$string = 'data["response"]["url"]';
$string = 'data["entry"]["0"]["text"]';

How can I convert the strings into a variable to access the proper array element? This method will need to work across any array at any of the dimensions.

 Answers

1

Quick and dirty:

echo eval('return $'. $string . ';');

Of course the input string would need to be be sanitized first.

If you don't like quick and dirty... then this will work too and it doesn't require eval which makes even me cringe.

It does, however, make assumptions about the string format:

<?php
$data['response'] = array(
    'url' => 'http://www.testing.com'
);

function extract_data($string) {
    global $data;

    $found_matches = preg_match_all('/["([a-z]+)"]/', $string, $matches);
    if (!$found_matches) {
            return null;
    }

    $current_data = $data;
    foreach ($matches[1] as $name) {
            if (key_exists($name, $current_data)) {
                    $current_data = $current_data[$name];
            } else {
                    return null;
            }
    }

    return $current_data;
} 

echo extract_data('data["response"]["url"]');
?>
Monday, November 28, 2022
1

To add to Rikesh's answer:

<?php
$aryMain = array(array('hello','bye'), array('',''),array('','')); 
$aryMain = array_filter(array_map('array_filter', $aryMain));
print_r($aryMain);

?>

Sticking his code into another array_filter will get rid of the entire arrays themselves.

Array
(
    [0] => Array
        (
            [0] => hello
            [1] => bye
        )

)

Compared to:

$aryMain = array_map('array_filter', $aryMain);

Array
(
    [0] => Array
        (
            [0] => hello
            [1] => bye
        )

    [1] => Array
        (
        )

    [2] => Array
        (
        )

)
Monday, October 31, 2022
 
1

Based on your given code, we can reverse-engineer the structure of $arr2 to (assuming R, G and B are integer from 0 to 255):

$arr2 = array(
   0 => array(
      0 => array(
        "R" => 128,
        "G" => 64,
        "B" => 255
      ),
      1 => array(
        ...
      ) 
   )
);

Given that your $SIZE is set to 256, you will have a total of 256*256=65536 arrays further containing arrays with key-values for R, G and B, resulting in total of 256*256*3=196608 integers in 3 levels of hierarchy. No surprise your code is slow!

I think the best strategy here is to try to reduce the total number of items in your array.

Given that instead of encoding single cells as "R, G, B" triples, you could encode all values in a single integer. Such as instead of:

0 => array( "R" => $r, "G" => $g, "B" => $b )

Given that 0<=r,g,b<=255, you could encode $arr2 as:

0 => ($r<<16 + $g<<8 + $b);

Now of course you need to unpack the color value inside your loop as well. This can be achieved by:

$col = $arr2[$y][$x];
$col_b = ($col&255);
$col_g = ($col>>8)&255;
$col_r = ($col>>16)&255;
$r .= $col_r.":";
$g .= $col_g.":";
$b .= $col_b.":";

This modification alone would cut one level of hierarchy from your array completely.

While running your original code with $SIZE=256, my average execution speed in my settings was 0.30 secs. With the given refactoring, I was able to reduce this to 0.10 secs cutting your calculation time to 1/3 of the original.

You will still have a lot of work to do if you wish to improve the performance, but I hope this gives you an idea on how you could proceed.

Monday, August 1, 2022
 
drtrd
 
2

Use like this.

List<String> stockList = new ArrayList<String>();
stockList.add("stock1");
stockList.add("stock2");

String[] stockArr = new String[stockList.size()];
stockArr = stockList.toArray(stockArr);

for(String s : stockArr)
    System.out.println(s);
Tuesday, October 25, 2022
 
2

I would suggest using the members of string, but with an explicit encoding:

byte[] bytes = text.getBytes("UTF-8");
String text = new String(bytes, "UTF-8");

By using an explicit encoding (and one which supports all of Unicode) you avoid the problems of just calling text.getBytes() etc:

  • You're explicitly using a specific encoding, so you know which encoding to use later, rather than relying on the platform default.
  • You know it will support all of Unicode (as opposed to, say, ISO-Latin-1).

EDIT: Even though UTF-8 is the default encoding on Android, I'd definitely be explicit about this. For example, this question only says "in Java or Android" - so it's entirely possible that the code will end up being used on other platforms.

Basically given that the normal Java platform can have different default encodings, I think it's best to be absolutely explicit. I've seen way too many people using the default encoding and losing data to take that risk.

EDIT: In my haste I forgot to mention that you don't have to use the encoding's name - you can use a Charset instead. Using Guava I'd really use:

byte[] bytes = text.getBytes(Charsets.UTF_8);
String text = new String(bytes, Charsets.UTF_8);
Sunday, December 18, 2022
 
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 

Browse Other Code Languages