1

as you can see in my code below, I'm using the same code (foreach loop with array assignment and trailing json_decode) three times for three variables that are structured similarly. I'm wondering how I can optimize my code so that it doesn't repeat functions unnecessarily. Would variable variables be helpful in this situation? Can I move the recurring lines of code to inside the first foreach statement?

Here's what my code looks like now:

date_default_timezone_set('America/Los_Angeles');

$stocks = array('MSFT' => 'http://ichart.finance.yahoo.com/table.csv?s=MSFT', 'AAPL' => 'http://ichart.finance.yahoo.com/table.csv?s=AAPL', 'FB' => 'http://ichart.finance.yahoo.com/table.csv?s=FB', 'ZNGA' => 'http://ichart.finance.yahoo.com/table.csv?s=ZNGA');

foreach ($stocks as $key=>$stock) {
    $fh = fopen($stock, 'r');
    $header = fgetcsv($fh);

    $varname = $key . '_data';

    $$varname  = array();
    while ($line = fgetcsv($fh)) {
        ${$varname}[count($$varname)] = array_combine($header, $line);
    }

    fclose($fh);
}

foreach($MSFT_data as $val){
    $MSFT[] = array((strtotime($val['Date']) * 1000), ((float)$val['Close']));
}
$MSFT = json_encode(array_reverse($MSFT));

foreach($AAPL_data as $val){
    $AAPL[] = array((strtotime($val['Date']) * 1000), ((float)$val['Close']));
}
$AAPL = json_encode(array_reverse($AAPL));

foreach($FB_data as $val){
    $FB[] = array((strtotime($val['Date']) * 1000), ((float)$val['Close']));
}
$FB = json_encode(array_reverse($FB));

Thanks. Let me know if you have any questions.

2
  • 1
    Why are you creating variable names dynamically but not just use an associative array? Commented Mar 11, 2013 at 2:51
  • This is a question I've been wondering for long enough, how to do a foreach loop for more than 1 array with the same number of elements and for each of them at the same time. Commented Mar 11, 2013 at 3:08

2 Answers 2

1

For the three loops, try:

function dateCloseLoop($data) {
    foreach($data as $val){
        $tmp[] = array((strtotime($val['Date']) * 1000), ((float)$val['Close']));
    }
    return json_encode(array_reverse($tmp));
}

So your code would be something like:

$MSFT = dateCloseLoop($MSFT_data);
$AAPL = dateCloseLoop($AAPL_data);
$FB = dateCloseLoop($FB_data);
Sign up to request clarification or add additional context in comments.

Comments

1

You could just use an associative array, storing a data array for each stock key, and use nested foreach's on that nested array.

Something like this:

$res = array();
$stocks = array('MSFT' => '...', 'AAPL' => '...', 'FB' => '...', 'ZNGA' => '...');

foreach ($stocks as $stock => $url) {
    $fh = fopen($url, 'r');
    $header = fgetcsv($fh);

    $res[$stock] = array();

    while ($line = fgetcsv($fh)) {
        $res[$stock][] = array_combine($header, $line);
    }

    fclose($fh);
}

$json = array();

foreach ($res as $stock => $data) {
    $out = array();
    foreach($data as $val){
        $out[] = array((strtotime($val['Date']) * 1000), ((float)$val['Close']));
    }
    $json[$stock] = json_encode(array_reverse($out));
}

3 Comments

I like the idea of this solution because it would be easy to add data just by adding an item to the $stocks array, but when I tried this code (added in URLs too) it did not work.
Which part didn't work? Is it not the output format you're looking for, or did it throw an error? It's working on my local setup.
I'm using the data in a Highcharts (jQuery data visualization plugin) implementation and for some reason the arrays aren't being passed into my JS.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.