• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

array_rand | nachbauen

Loon3y

Neues Mitglied
Morgen...

stehe vor folgendem problem..ich soll den befehl array_rand für eine beliebige anzahl von ausgaben aus einen array nachbauen..darf dafür kein array_rand benutzen...

wie soll ich das anstellen?! Hänge grad total...*seufz*

Gruß
Loon3y
 
Aber rand() darfst du benutzen? Dann ist es doch relativ einfach, musst die bei der Mehrfachauswahl nur eine Hash-List anlegen, um zu prüfen, ob die diesen Index schon hast. Etwas schwieriger wird es, wenn das ganze auch noch mit nicht-numerischen Indizes funktionieren muss.
 
genau das soll es ja! soll mit allen indizen funzen....hmpf...glaub ich bin zu dumm das zu machen.
 
Ich hab mich mal probiert:
PHP:
<?php
function array_rand_new($arr, $num = 1)
{
	$keys = array_keys($arr);
	$num_keys = count($keys);

	if ($num > $num_keys) {
		// eigentlich Warning der Form: array_rand(): Second argument has to be between 1 and the number of elements in the array
		return NULL;
	}

	if ($num < 2) {
		return $keys[rand(0, $num_keys - 1)];
	} else {
		$random_keys = array(); // Hashliste, interessieren nur die Keys, Werte sind egal deshalb immer 1

		for ($i = 1; $i <= $num; $i++) {
			do {
				$key = rand(0, $num_keys - 1);
			} while(isset($random_keys[$keys[$key]]));

			$random_keys[$keys[$key]] = 1;
		}

		return array_keys($random_keys);
	}

}

$myarr = array('bar' => 1, 'foo' => 2, 'baz' => 3);
var_dump(array_rand($myarr, 2));
var_dump(array_rand_new($myarr, 2));
Einzige Frage, die zu klären bleibt: Was passiert bei verschachtelten Arrays.
 
@crash warum setzt du die elemente des array zuerst 1 und die eigentlichen werte werden zu schlüsseln? die werte soll es eigentlich als element haben!
und dann eliminierst du wieder die werte und gibst nur die schlüssel zurück

so sparst du dir diesen umweg (ungetestet)
PHP:
$random_keys = array();
for ($i = 1; $i <= $num; $i++) { 
  do {
                $key = rand(0, $num_keys - 1);
            } while(in_array($keys[$key], $random_keys));

            $random_keys[] = $keys[$key]; 
}
return $random_keys;
 
hm...schwer zu sagen wie das geht...hab mir deins mal durchgelesen..und mit meinen bisherigen "fortschritt" verglichen..irgendwie hab ich was falsch....was passt da nicht? wo liegt der denkfehler?

PHP:
$var = array(
    1 => "das ist test0",
    "test1" => "hallo du", 
    "test2" => "hallo welt",
    "test3" => 123456,
    "test4" => 6543,
    "test5" => 987,
    "test6" => "dad"
);

$anzahl = 5;

function nachbau_arrayrand($var, $anzahl){
    if(!is_int($anzahl))
        return "";
    if($anzahl > count($var))
        return "error";
    if($anzahl == 0)
        return "error";
    else{
        foreach(range(0, $anzahl) as $array_zufall)
            return $array_zufall;
    }
}
 
Weil Hashlist+isset() schneller ist als in_array(). ;)

*edit*
Zur Info: Bei 0 und kleiner wird oberes erwähntes Warning ausgegeben und NULL zurückgegeben. array_rand() frisst auch Ziffern in Strings, sonst wird auch das Warning ausgegeben und NULL returned.

Loon3y: ich weiß nicht warum du da mir foreach() ran willst, du musst ja nicht jeden Element anfassen, sondern nur eine konkrete Menge von zufälligen Indizes des Arrays erzeugen.
 
Zuletzt bearbeitet:
Loon3y: ich weiß nicht warum du da mir foreach() ran willst, du musst ja nicht jeden Element anfassen, sondern nur eine konkrete Menge von zufälligen Indizes des Arrays erzeugen.

ka komm irgendwie garnet weiter :|

Edit:

PHP:
        for ($i = 1; $i <= $num; $i++) {
            do {
                $key = rand(0, $num_keys - 1);
            } while(isset($random_keys[$keys[$key]]));

            $random_keys[$keys[$key]] = 1;
        }
dies versteh ich nicht so ganz..könnte das wer erklären? :-(
 
Zuletzt bearbeitet:
ka komm irgendwie garnet weiter :|

Edit:

PHP:
        for ($i = 1; $i <= $num; $i++) {
            do {
                $key = rand(0, $num_keys - 1);
            } while(isset($random_keys[$keys[$key]]));

            $random_keys[$keys[$key]] = 1;
        }
dies versteh ich nicht so ganz..könnte das wer erklären? :-(

Zunächst einmal durchläufst du mit der for-schleife alle elemente des arrays das du übergeben hast.

mit der do { ... } while(bedingung); schleife wird zufällig ein element des übergebenen arrays ausgewählt und sein schlüssel als schlüssel im array $radnom_keys gespeichert ($keys enthält ja alle schlüssel des übergebenen arrays stichwort: array_keys($arr))
Ja und die Bedingung der schleife ist eben. erzeuge so lange eine zufallszahl bis ein element des übergebenen arrays getroffen wurde, das noch nicht schlüssel von $random_keys ist.

ich denke das war es eigentlich :)
 
bitte verwendet die funktion php.net/mt_rand
ist zufälliger ;) :-D
 
Stimmt mt_rand() ist natürlich besser. Fragt sich nur, welchen Algorithmus array_rand() selbst benutzt. Die for-Schleife durchläuft das Array nicht, die erzeugt nur so viele Schlüssel wie gefordert werden.
 
so..zwei lösungen von mir:

PHP:
$aSrc = array(
    1 => "das ist ein test",
    "test1" => "hallo du", 
    "test2" => "hallo welt",
    "test3" => 123456,
    "test4" => 6543,
    "test5" => 987,
    "test6" => "dad"
);

$anzahl = 5;
function nachbau_arrayrand($aSrc, $anzahl){
    if(count($aSrc) == 0)
        return null;
    if(!is_int($anzahl) || $anzahl <= 0)
        return null;
    if($anzahl > count($aSrc))
        return null;
    $aReturn = array();
    for($i = 1; count($aReturn) <= $anzahl; $i++){
        $key = rand(1, count($aSrc)-1);
        $j = 0;
        foreach($aSrc as $k => $v){
            $j++;
            if($j == $key && !in_array($k, $aReturn))
                array_push($aReturn, $k);
        }
    }
    return $aReturn;
}
echo "\nNachbau:\n";
print_r(nachbau_arrayrand($aSrc, $anzahl)) ."\n";

echo "\nOriginal:\n";
print_r(array_rand($aSrc, $anzahl));
oder:

PHP:
$aSrc = array(
    1 => "das ist ein test",
    "test1" => "hallo du", 
    "test2" => "hallo welt",
    "test3" => 123456,
    "test4" => 6543,
    "test5" => 987,
    "test6" => "dad"
);

$anzahl = 5;

function nachbau_arrayrand($aSrc, $anzahl){
    if(count($aSrc) == 0)
        return null;
    if(!is_int($anzahl) || $anzahl <= 0)
        return null;
    if($anzahl > count($aSrc))
        return null;
    $aKeys = array_keys($aSrc);
    $aReturn = array();
    while(count($aReturn) < $anzahl){
        $key = rand(0, count($aKeys)-1);
        array_push($aReturn, $aKeys[$key]);
        unset($aKeys[$key]);
        $aKeys = array_values($aKeys);
    }
    return $aReturn;
}

echo "\nNachbau:\n";
print_r(nachbau_arrayrand($aSrc, $anzahl)) ."\n";

echo "\nOriginal:\n";
print_r(array_rand($aSrc, $anzahl));
Bitte um Kritik / Verbesserungsmöglichkeiten / Lob ^^
 
wenn schon alle so fleißig helfen will ich auch mal mitmachen xD

PHP:
/**
 * @PARAM array $input
 * @PARAM int $num_req
 * @RETURN mixed
 */
function _array_rand($input, $num_req = 1) {
	// check $input type
	if(!is_array($input)) {
		die('Illegal argument'); // or throw an exception ;)
	}

	// check $num_req type
	if(!is_int($num_req)) {
		die('Illegal argument'); // or throw an exception ;)
	}

	// check $num_req size
	if($num_req < 1) {
		die('Illegal argument'); // or throw an exception ;)
	}

	// define needed vars
	$idxArray = array();
	$returning = array();

	// get some random numbers
        $arraySize = count($input) - 1;
	for($i = 0; $i < $num_req; $i++) {
		do {
			$randomNumber = mt_rand(0, $arraySize);
		} while(in_array($randomNumber, $idxArray));
		array_push($idxArray, $randomNumber);
	}

	// get the array keys
	$index = 0;
	foreach($input as $key => $val) {
		if(in_array($index, $idxArray)) {
			array_push($returning, $key);
		}
		$index++;
	}

	return (count($returning) == 1 ? $returning[0] : $returning);
}
 
Zuletzt bearbeitet von einem Moderator:
Die for-Schleife durchläuft das Array nicht, die erzeugt nur so viele Schlüssel wie gefordert werden.
und es werden so viele schlüssel gefordert wie das array elemente hat. okay die formulierung von mir ist vielleicht nicht ganz korrekt. :) das ergebnis ist aber das gleiche, da $num der menge an elementen im array entspricht
 
Noe. $num entspricht dem zweiten Parameter und nicht count().
An alle: Ihr solltest wirklich eine Hashlist nutzen, in_array() wird bei großen Arrays einfach zu langsam.
 
also wenn es darum geht die array_rand funktion nachzubauen, die liefert immer ein element aus der ersten dimension. wenn man sich ein array erstellt das so mit den werden gefüllt ist das man array_rand umbauen muss auf mehrere dimensionen hat man was falsch gemacht ;)
 

Neueste Beiträge

Zurück
Oben