tags:

views:

256

answers:

7

I asked this question before, Here however I think I presented the problem poorly, and got quite a few replies that may have been useful to someone but did not address the actual question and so I pose the question again.

Is there a single-line native method in php that would allow me to do the following. Please, please, I understand there are other ways to do this simple thing, but the question I present is does something exist natively in PHP that will grant me access to the array values directly without having to create a temporary array.

$rand_place = explode(",",loadFile("csvOf20000places.txt")){rand(0,1000)};

This is a syntax error, however ideally it would be great if this worked!

Currently, it seems unavoidable that one must create a temporary array, ie

The following is what I want to avoid:

$temporary_places_array = explode(",",loadFile("csvOf20000places.txt"));
$rand_place = $temporary_places_array[rand(0,1000)];

Also, i must note that my actual intentions are not to parse strings, or pull randomly from an array. I simply want access into the string without a temporary variable. This is just an example which i hope is easy to understand. There are many times service calls or things you do not have control over returns an array (such as the explode() function) and you just want access into it without having to create a temporary variable.

NATIVELY NATIVELY NATIVELY, i know i can create a function that does it.

+3  A: 

No, there is no way to do that natively.

You can, however:

1.- Store the unavoidable array instead of the string. Given PHP's limitation this is what makes most sense in my opinion.

Also, don't forget you can unset()

2.- Use strpos() and friends to parse the string into what you need, as shown in other answers I won't paste here.

3.- Create a function.

Vinko Vrsalovic
In your example, you gave yourself the liberty of making $places a temporary array .... which defeats the entire purpose of this question.
Vinh
I'm actually suggesting you use an array instead of the CSV string. I say so in the third paragraph. The idea is to avoid storing the string, because I understand that your concern is duplication of storage.
Vinko Vrsalovic
A: 

If it's memory concerns, there are other ways of going about this that don't split out into an array. But no, there is nothing builtin to handle this sort of situation.

As an alternative, you might try:

$pos = 0;
$num = 0;
while(($pos = strpos($places, ',', $pos+1)) !== false) {$num++;}
$which = rand(0, $num);
$num = 0;
while($num <= $which) {$pos = strpos($places, ',', $pos+1);}
$random_place = substr($places, $pos, strpos($places, ',', $pos+1));

I havn't tested this, so there may be a few off-by-one issues in it, but you get the idea. This could be made shorter (and quicker) by cacheing the positions that you work out in the first loop, but this brings you back to the memory issues.

Matthew Scharley
+1  A: 

There is no native PHP method of doing this.

You could make a function like this:

function array_value($array, $key) {
    return $array[$key];
}

And then use it like this:

$places = "alabama,alaska,arizona .... zimbabway"; 
$random_place = array_value(explode(",", $places), rand(0, 1000));
yjerem
i know i can create a function that does this... my question is specifically address a native php method.
Vinh
A: 

You can do this:

<?php
function foo() {
    return new ArrayObject(explode(",", "zero,one,two"));
}
echo foo()->offsetGet(1);    // "one"
?>

Sadly you can't do this:

echo (new ArrayObject(explode(",", "zero,one,two")))->offsetGet(2);
nickf
+1  A: 

I know it's poor form to answer a question with a question, but why are you concerned about this? Is it a nitpick, or an optimization question? The Zend engine will optimize this away.

However, I'd point out you don't have to create a temporary variable necessarily:

$rand_place = explode(",",loadFile("csvOf20000places.txt"));
$rand_place = $rand_place[rand(0,1000)];

Because of type mutability, you could reuse the variable. Of course, you're still not skipping a step.

Jim Nelson
I ask simply because I don't want the extra line of code, lets say it was for a compeititon to see who could use the least amount of characters to do something (yea you'd probalby want to use perl and not php) but that's why i'm asking.
Vinh
A: 

I spent a great deal of last year researching advanced CSV parsing for PHP and I admit it would be nice to randomly seek at will on a file. One of my semi-deadend's was to scan through a known file and make an index of the position of all known \n's that were not at the beginning of the line.

   //Grab and load our index
$index = unserialize(file_get_contents('somefile.ext.ind'));
//What it looks like
$index = array( 0 => 83, 1 => 162, 2 => 178, ....);

$fHandle = fopen("somefile.ext",'RB');
$randPos = rand(0, count($index));
fseek($fHandle, $index[$randPos]);
$line = explode(",", fgets($fHandle));

Tha's the only way I could see it being done anywhere close to what you need. As for creating the index, that's rudimentary stuff.

$fHandle = fopen('somefile.ext','rb');
$index = array();
for($i = 0; false !== ($char = fgetc($fHandle)); $i++){
      if($char === "\n") $index[] = $i;     
}
David
+1  A: 
list($rand_place) = array_slice(explode(',', loadFile("csvOf20000places.txt")), array_rand(explode(',', loadFile("csvOf20000places.txt"))), 1);

EDIT: Ok, you're right. The question is very hard to understand but, I think this is it. The code above will pull random items from the csv file but, to just pull whatever you want out, use this:

list($rand_place) = array_slice(explode(',', loadFile("csvOf20000places.txt")), {YOUR_NUMBER}, 1);

Replace the holder with the numeric key of the value you want to pull out.

Stephen
Damn, I spent some time on this. How is it now the answer you were looking for?
Stephen