<?xml version="1.0"?>
<rss version="2.0">
	<channel>
		<title>C++ pick a random element from a vector?</title>
		<link>http://www.allegro.cc/forums/view/616281</link>
		<description>Allegro.cc Forum Thread</description>
		<webMaster>matthew@allegro.cc (Matthew Leverton)</webMaster>
		<lastBuildDate>Thu, 19 May 2016 21:07:43 +0000</lastBuildDate>
	</channel>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>simplest approach is to:
</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">int</span> random_int<span class="k2">(</span><span class="k1">int</span> min, <span class="k1">int</span> max<span class="k2">)</span>
<span class="k2">{</span>
   <span class="k1">return</span> <a href="http://www.delorie.com/djgpp/doc/libc/libc_637.html" target="_blank">rand</a><span class="k2">(</span><span class="k2">)</span>%<span class="k2">(</span>max-min<span class="k3">+</span><span class="n">1</span><span class="k2">)</span> <span class="k3">+</span> min<span class="k2">;</span>
<span class="k2">}</span>

<span class="k1">template</span><span class="k3">&lt;</span><span class="k1">class</span> T&gt;
T random_element<span class="k2">(</span>std::vector<span class="k3">&lt;</span>T&gt; <span class="k3">&amp;</span>elements<span class="k2">)</span>
<span class="k2">{</span>
   <span class="k1">return</span> elements<span class="k2">[</span>random_int<span class="k2">(</span><span class="n">0</span>, elements.size<span class="k2">(</span><span class="k2">)</span><span class="k3">-</span><span class="n">1</span><span class="k2">)</span><span class="k2">]</span><span class="k2">;</span>
<span class="k2">}</span>
</pre></div></div><p>

Problem is what should the behavior be when <span class="source-code">elements</span> is empty?  I can&#39;t find a solution!
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Mark Oates)</author>
		<pubDate>Thu, 19 May 2016 02:19:31 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/616281/1022671#target">Mark Oates</a> said:</div><div class="quote"><p>
Problem is what should the behavior be when elements is empty? I can&#39;t find a solution!
</p></div></div><p>
An exception? How is &quot;random element&quot; any different than trying to get the &quot;last&quot; element of an empty array?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Chris Katko)</author>
		<pubDate>Thu, 19 May 2016 02:39:41 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/616281/1022673#target">Chris Katko</a> said:</div><div class="quote"><p> any different than trying to get the &quot;last&quot; element of an empty array?</p></div></div><p>Oh, interesting.</p><p>Without knowing too much about this, it seems like <span class="source-code">back<span class="k2">(</span><span class="k2">)</span></span> just simply segfaults.  I&#39;m not to familiar with how exceptions should be used in this case.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Mark Oates)</author>
		<pubDate>Thu, 19 May 2016 03:55:08 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>An exception would be the only possible solution (short of crashing). Trying to get &quot;any&quot; element from an empty set is undefined. It doesn&#39;t make sense. Arguably you could return something like null/undefined in languages with first-class support for it, but that too would be likely to cause havoc. An exception makes the most sense.</p><p><b>Append:</b></p><p>To clarify, <span class="source-code">std::vector::operator<span class="k2">[</span><span class="k2">]</span></span> will indeed crash here on an empty set. We&#39;re suggesting that <i>you</i> should throw an exception. If you use <span class="source-code">std::vector::at<span class="k2">(</span><span class="k2">)</span></span> instead of <span class="source-code"><span class="k1">operator</span><span class="k2">[</span><span class="k2">]</span></span> that will handle the bounds checking for you. For performance sensitive code crashing is probably acceptable though... Programmer should have checked...
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (bamccaig)</author>
		<pubDate>Thu, 19 May 2016 04:09:47 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Would <span class="source-code">back<span class="k2">(</span><span class="k2">)</span></span> throw an exception on an empty set?</p><p>Am I creating new, non-standard behavior?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Mark Oates)</author>
		<pubDate>Thu, 19 May 2016 04:45:13 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title"><a href="http://www.cplusplus.com/reference/vector/vector/back/">vector::back - C++ Reference</a> said:</div><div class="quote"><p>Calling this function on an empty container causes undefined behavior.</p></div></div><p>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (bamccaig)</author>
		<pubDate>Thu, 19 May 2016 06:15:30 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Ok cool.</p><p>Exception would be nice.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Mark Oates)</author>
		<pubDate>Thu, 19 May 2016 06:26:17 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>If you use a vector of pointers to the actual elements, the solution is simple..<br />If empty just return NULL. Besides.. sorting, iterating, searching such a vector is MUCH faster !<br />I don think you can do that with a template function though.. never tried
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Ariesnl)</author>
		<pubDate>Thu, 19 May 2016 12:54:36 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>You could add something like this for pointer types.
</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">template</span> <span class="k3">&lt;</span><span class="k1">class</span> T&gt;
T<span class="k3">*</span> try_random_element<span class="k2">(</span>std::vector<span class="k3">&lt;</span>T<span class="k3">*</span><span class="k3">&gt;</span> <span class="k3">&amp;</span>elements<span class="k2">)</span>
<span class="k2">{</span>
  <span class="k1">if</span> <span class="k2">(</span>elements.size<span class="k2">(</span><span class="k2">)</span> <span class="k3">=</span><span class="k3">=</span> <span class="n">0</span><span class="k2">)</span>
  <span class="k2">{</span>
    <span class="k1">return</span> nullptr<span class="k2">;</span>
  <span class="k2">}</span>
  <span class="k1">else</span> <span class="k1">return</span> random_element<span class="k2">(</span>elements<span class="k2">)</span><span class="k2">;</span>
<span class="k2">}</span>
</pre></div></div><p>

C++17 may include the optional type which would be useful for this case if you don&#39;t want to use exceptions.</p><p>You might also want to consider using the C++11+ random header. It has far more options than C&#39;s rand and should also yield similar results on different compilers.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (l j)</author>
		<pubDate>Thu, 19 May 2016 13:30:01 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>What are you intending to use this code in? Keep in mind that exceptions in C++ are slow as <span class="cuss"><span><span class="cuss"><span>shit</span></span></span></span>, so you really don&#39;t want to use them in code that runs every frame (or, god forbid, multiple times per frame). In that case, some kind of &quot;error&quot; return value, defined by you, would be favorable. Of course that is hard to do with templates, so T* might indeed be easier than T.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (RPG Hacker)</author>
		<pubDate>Thu, 19 May 2016 14:26:36 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Depending on what classes you use it for, it may be more practical for the template to return &quot;the default value of T&quot;.<br />For pointers it will be NULL, for numbers it will be zero.<br />For your own classes, it will be the result of the default constructor.</p><p>From what I read, it seems you do it by typing <span class="source-code"><span class="k1">return</span> T<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></span>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Audric)</author>
		<pubDate>Thu, 19 May 2016 14:27:23 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I know that Haskell and Rust return an optional value, Python throws an error. </p><p>You could try returning an iterator rather than the value:
</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">template</span> <span class="k3">&lt;</span><span class="k1">typename</span> _Coll&gt;
<span class="k1">typename</span> _Coll::const_iterator choice<span class="k2">(</span><span class="k1">const</span> _Coll<span class="k3">&amp;</span> v<span class="k2">)</span> <span class="k2">{</span>
  <span class="k1">if</span> <span class="k2">(</span>v.empty<span class="k2">(</span><span class="k2">)</span><span class="k2">)</span> <span class="k2">{</span>
    <span class="k1">return</span> v.end<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
  <span class="k2">}</span>
  <span class="k1">else</span> <span class="k2">{</span>
    <span class="k1">return</span> std::next<span class="k2">(</span>v.begin<span class="k2">(</span><span class="k2">)</span>, <a href="http://www.delorie.com/djgpp/doc/libc/libc_637.html" target="_blank">rand</a><span class="k2">(</span><span class="k2">)</span> % v.size<span class="k2">(</span><span class="k2">)</span><span class="k2">)</span><span class="k2">;</span>
  <span class="k2">}</span>
<span class="k2">}</span>
</pre></div></div><p>
and checking it:
</p><div class="source-code"><div class="toolbar"><span class="button numbers"><b>#</b></span><span class="button select">Select</span><span class="button expand">Expand</span></div><div class="inner"><span class="number">  1</span><span class="k1">int</span> main<span class="k2">(</span><span class="k2">)</span>
<span class="number">  2</span><span class="k2">{</span>
<span class="number">  3</span>  
<span class="number">  4</span>  std::vector<span class="k3">&lt;</span>std::string&gt; values<span class="k2">{</span><span class="s">"Eggs"</span>, <span class="s">"Cheese"</span>, <span class="s">"Bacon"</span>, <span class="s">"Apples"</span>, <span class="s">"Soup"</span>, <span class="s">"Beer"</span><span class="k2">}</span><span class="k2">;</span>
<span class="number">  5</span>
<span class="number">  6</span>  <span class="k1">for</span> <span class="k2">(</span><span class="k1">int</span> i <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span> i <span class="k3">&lt;</span> <span class="n">100</span><span class="k2">;</span> <span class="k3">+</span><span class="k3">+</span>i<span class="k2">)</span> <span class="k2">{</span>
<span class="number">  7</span>    <span class="k1">auto</span> v <span class="k3">=</span> choice<span class="k2">(</span>values<span class="k2">)</span><span class="k2">;</span>
<span class="number">  8</span>    <span class="k1">if</span> <span class="k2">(</span>v <span class="k3">=</span><span class="k3">=</span> values.end<span class="k2">(</span><span class="k2">)</span><span class="k2">)</span> <span class="k2">{</span>
<span class="number">  9</span>      std::cout <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="s">"You are an idiot"</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> std::endl<span class="k2">;</span>
<span class="number"> 10</span>    <span class="k2">}</span>
<span class="number"> 11</span>    <span class="k1">else</span> <span class="k2">{</span>
<span class="number"> 12</span>      std::cout <span class="k3">&lt;</span><span class="k3">&lt;</span> i <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="s">'\t'</span> <span class="k3">&lt;</span><span class="k3">&lt;</span> <span class="k3">*</span>v <span class="k3">&lt;</span><span class="k3">&lt;</span> std::endl<span class="k2">;</span>
<span class="number"> 13</span>    <span class="k2">}</span>
<span class="number"> 14</span>  <span class="k2">}</span>
<span class="number"> 15</span>    <span class="k1">return</span> <span class="n">0</span><span class="k2">;</span>
<span class="number"> 16</span><span class="k2">}</span>
</div></div><p>

Also note that <span class="source-code"><a href="http://www.delorie.com/djgpp/doc/libc/libc_637.html" target="_blank">rand</a><span class="k2">(</span><span class="k2">)</span> % X</span> is not the best way to get uniform values between 0 and X-1.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Peter Hull)</author>
		<pubDate>Thu, 19 May 2016 16:21:52 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/616281/1022703#target">Peter Hull</a> said:</div><div class="quote"><p>Also note that rand() % X is not the best way to get uniform values between 0 and X-1.</p></div></div><p>
(The word you&#39;re looking for is &quot;equiprobable&quot;)<br />A more likely problem is to compile the code with Microsoft&#39;s compiler, RAND_MAX is only 32767, so items above this number NEVER get randomly selected.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Audric)</author>
		<pubDate>Thu, 19 May 2016 17:40:31 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Exceptions are relatively slow. Relative is relative.</p><p>Trying to use a method that requires elements to exist, when there are none, is a violation of the <a href="https://dlang.org/spec/contracts.html">pre-conditions</a> of the contract.</p><p> - Returning an in-stream value, null, is dangerous. It&#39;s also atypical C++, so it should be used with caution when surrounded by typical C++-code. Surrounding code is a clue to the usage of other code.</p><p> - Exceptions shouldn&#39;t be firing off every 10 frames. They should be firing off to tell you that you did something wrong at run-time. Also consider asserts. (The only time I really use exceptions is when the resource or action is truly blackboxed, like trying to access a SQL database and the database could lose connection on any call--that would be impossible to check every call before hand--it could fail between the check and the actual call!)</p><p> - Regardless of the method of error notification, it is a error condition and code should either be expected to be an impossible condition to achieve, or users should be expected to check and guarantee array size before using. Calling that function without data means that calling code block is broken.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Chris Katko)</author>
		<pubDate>Thu, 19 May 2016 17:50:31 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title"><a href="http://www.allegro.cc/forums/thread/616281/1022705#target">Chris Katko</a> said:</div><div class="quote"><p> Exceptions are relatively slow. Relative is relative.</p><p> [...]</p><p> Exceptions shouldn&#39;t be firing off every 10 frames. They should be firing off to tell you that you did something wrong at run-time.</p></div></div><p>This is the important part here. Exceptions are fine as long as they&#39;re only thrown when an actual error condition is met, so if you define that calling random_element() on an array with a length of 0 is not an error condition, then the function definitely shouldn&#39;t throw an exception when the array is empty. Or in other words: Throwing an exception while your code is behaving &quot;as itended&quot; is a bad idea, at least in C++. So whether you throw an execption here or not really depends on how you define your random_element() function and what you want to achieve. Do you consider a call to this function with an empty array an error? Throw an exception. Do you consider such a call valid and want the application to respond in a specific way to it? Don&#39;t throw an exception and instead return a default value or something like that.</p><p>Throwing an exception while in a valid condition can have dramatic effects on performance if you do this every frame or even more often than that. I could experience this first-hand some time ago when coding a TMX map renderer. I used std::maps and std::vectors to hold some of my map data. Now after loading the map, I wanted to iterate over its data (don&#39;t know if it was a map or a vector, I think the former) to do some stuff with and just ignore non-existing elements. For non-existing elements, I just caught the exception that was thrown. Now I don&#39;t know how I did this back then, but I somehow managed to accidently also have this code running at runtime instead of just after map creation. The result was that the FPS in my game immediately dropped from 60 to 10 or somewhere around that. I was quite surprised, until I realised that my code was throwing dozens of exceptions each frame.</p><p>So yeah, throwing exceptions in realtime code is definitely not recommended.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (RPG Hacker)</author>
		<pubDate>Thu, 19 May 2016 20:10:19 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>For all intents and purposes, places where performance matters that much can spend the extra ms checking first. Or you can provide an alternative overload that doesn&#39;t throw.</p><p>The alternative is multiple return values, and the workaround in languages that don&#39;t support that is an &quot;output&quot; parameter:</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">template</span><span class="k3">&lt;</span><span class="k1">typename</span> T&gt;
<span class="k1">bool</span> random_element<span class="k2">(</span><span class="k1">const</span> std::vector<span class="k3">&lt;</span>T&gt; <span class="k3">&amp;</span> v, T<span class="k3">&amp;</span> element<span class="k2">)</span><span class="k2">;</span>
</pre></div></div><p>

This has the unfortunate side-effect that the caller has to do a bit more work to set up the call, but it has the advantage that no exception is needed and it still differentiates between all possible values of the container.</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">int</span> x<span class="k2">;</span>

<span class="k1">if</span><span class="k2">(</span>random_element<span class="k2">(</span>foo, x<span class="k2">)</span><span class="k2">)</span> <span class="k2">{</span>
    <span class="c">// x is random.</span>
<span class="k2">}</span> <span class="k1">else</span> <span class="k2">{</span>
    <span class="c">// x is undefined.</span>
<span class="k2">}</span>
</pre></div></div><p>

An iterator may be the better solution to avoid copying if the container has heavy objects, but I think that&#39;s going to end up leading to heavy copies eventually anyway so it&#39;s probably not the place to worry about it.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (bamccaig)</author>
		<pubDate>Thu, 19 May 2016 21:07:43 +0000</pubDate>
	</item>
</rss>
