27737

Angular JS ng-repeat choose random grouping from array?

Question:

I have an array of 6 objects.

I have a list with an ng-repeat where I want to display 3 unique items from those 6 items.

One each refresh, it might pull 3 different items, but it's ok if it does not, the only thing is that the 3 cannot have duplicates amongst themselves.

As an example, if the array is [red, yellow, blue, green, purple, cyan, fuchsia] then on refresh I could get:

red,blue,green purple,blue,yellow fuchsia,green,red

etc. As you can see, I don't care that blue came up twice in a row there, but I must never get red, blue, blue.

I have this code:

<ul class="ch-grid"> <li ng-repeat="user in home.testimonials|orderBy:random|limitTo: 3"> <div class="ch-item ch-img-1" style="background-image: url(assets/images/{{user.image}})"> <div class="ch-info"> <h3>{{user.quote}}</h3> </div> </div> <h3 class="name">{{user.name}}</h3> <p class="title">{{user.title}}

</li> </ul>

and them in my controller:

_this.random = function () { return 0.5 - Math.random(); }; _this.testimonials = [ { name: 'Sara Conklin', title: 'SMB/SendPro UX Architect', image: 'sara-conklin.jpg', quote: 'Instead of inventing original solutions, we can leverage DS guidelines and components, save time, ensure great UX and promote consistency. '}, { name: 'Jenn Church', title: 'User Experience Designer', image: 'jenn-church.jpg', quote: 'The Design System has been a great tool in rapid prototyping, allowing me to get modern, on-brand interfaces put together quickly without having to start from scratch.'}, { name: 'Peter Leeds', title: 'Global Creative and Brand Activation', image: 'peter-leeds.jpg', quote: 'Design System provides the unified, consistent look needed to preserve and reinforce the integrity of our brand.”'}, { name: 'Marcy Goode', title: 'Digital Marketing, Self Service &amp; Content Management Leader', image: 'marcy-goode.jpg', quote: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iusto, ipsam, mollitia in vitae nemo aliquam.'}, { name: 'Clarence Hempfield', title: 'Spectrum Spatial Analyst Product Manager', image: 'clarence.jpg', quote: 'Design System isn’t just about the interface. It’s about understanding how people are expecting to interact with your technology.'}, { name: 'Aaron Videtto', title: 'SendSuite Tracking Online Product Manager', image: 'aaron.jpg', quote: 'Customers of SendSuite Tracking Online have been up and running within 10-15 minutes. We were able to do this because of the Design System.'} ];

But it is not limiting to 3, I get dozens.

OK, trying the filter route as suggested by @csschapker:

(function () { 'use strict'; angular.module('pb.ds.home').filter('getThree', function () { return function (array) { var copy = angular.copy(array); var sample = []; while (sample.length < 3) { var randomIndex = Math.floor(Math.random() * (copy.length)); sample.push(copy[randomIndex]); } return sample; }; }); })();

and

<ul class="ch-grid"> <li ng-repeat="user in home.testimonials|filter:getThree"> <div class="ch-item ch-img-1" style="background-image: url(assets/images/{{user.image}})"> <div class="ch-info"> <h3>{{user.quote}}</h3> </div> </div> <h3 class="name">{{user.name}}</h3> <p class="title">{{user.title}}

</li> </ul>

This simply prints out all 6. I must be missing something.

Answer1:

User random and limitTo filters.

<p ng-repeat="i in list|orderBy:random|limitTo:3">{{i}}

Answer2:

<em>This answer is a good start for a filter but there are problems with it (see the comments). I would delete the answer but the comments may be useful to someone in the future. My new answer is a better way to solve this problem for now.</em>

You can use a custom filter:

.filter('randomSample', function() { return function(array, length) { var copy = angular.copy(array); var sample = []; while(sample.length < length) { var randomIndex = Math.floor(Math.random() * (copy.length)); sample.push(copy.splice(randomIndex, 1)[0]); } return sample; }; })

Use it like:

<li ng-repeat="item in array | randomSample:3">{{ item }}</li>

Here's an example on plnkr: <a href="http://plnkr.co/edit/NgsQlvgrCD7vLXnBC7q1?p=preview" rel="nofollow">http://plnkr.co/edit/NgsQlvgrCD7vLXnBC7q1?p=preview</a>

Answer3:

After many attempts, it looks like it is better to get the random values in your controller after the array is populated. Like so:

_this.sample = []; var copy = angular.copy(_this.testimonials); while(_this.sample.length < 3) { var randomIndex = Math.floor(Math.random() * (copy.length)); _this.sample.push(copy.splice(randomIndex, 1)[0]); }

Then just ng-repeat="user in home.sample"

Recommend

  • int.TryParse vs. other methods for determining if a char contains an int
  • Creating a subscription based website in ASP.NET
  • Install4j - How can I install the MSVC++ Redistributable Binary if needed?
  • Get OneDrive Item Id for Current Word doc
  • MongoDB capped collection and monotically increasing index
  • gridview on page won't refresh, even when calling databind again
  • Android text field: distance between line and text
  • ube error: _mm_aeskeygenassist_si128 intrinsic requires at least -xarch=aes
  • Does Windows Phone 7 have a standard Edit/Add/Delete convention?
  • ASP.NET Gridview Paging Problem
  • android.app.PendingIntent cannot be accessed ouside the package
  • How to get or calculate size of Azure File/Share or Service
  • PHP file_exists() anomaly
  • MVVM: Image Bind Source from FileOpenPicker
  • SQL - Select lowest values with group by and order by?
  • Cypher - matching two different possible paths and return both
  • how to populate a SQLite database and use that database in phonegap?
  • Activation Function choice for Neural network
  • Creating a DropDownList
  • How to set elevation color?
  • Who propagate bugfixes across branches (corporate development)?
  • Android Studio Can't Find tools.jar
  • UWP/C# - Issue with AQS and USB Devices
  • xcode don't localize specific strings
  • Authentication in Play! and RestEasy
  • Ensure fsync did its job
  • How to match http request and response using Jersey ContainerRequestFilter and ContainerResponseFilt
  • azure media services - The request body is too large and exceeds the maximum permissible limit
  • Syntax for setting draggablecursor property in google maps api
  • formatting the colorbar ticklabels with SymLogNorm normalization in matplotlib
  • ilmerge with a PFX file
  • Resize panoramic image to fixed size
  • Incrementing object id automatically JS constructor (static method and variable)
  • Does CUDA 5 support STL or THRUST inside the device code?
  • Microsoft Visual Studio Community 2015 always crashes in Windows 10 if swithed to Visual FoxPro
  • log4net write single file for each call to log.info
  • Can Visual Studio XAML designer handle font family names with spaces as a resource?
  • How can I remove ASP.NET Designer.cs files?
  • Are Kotlin's Float, Int etc optimised to built-in types in the JVM? [duplicate]
  • Running Map reduces the dimensions of the matrices