Array Sorting and Reducing

Array sorting is useful for obtaining custom quality mosaics which involve reducing a subset of image bands according to the values in a different band. The following example sorts by a cloud index, then gets the mean of the least cloudy subset of images in the collection:

Code Editor (JavaScript)

// Define an arbitrary region of interest as a point.
var roi = ee.Geometry.Point(-122.26032, 37.87187);

// Use these bands.
var bandNames = ee.List(['B2', 'B3', 'B4', 'B5', 'B6', 'B7', 'B10', 'B11']);

// Load a Landsat 8 collection.
var collection = ee.ImageCollection('LANDSAT/LC08/C01/T1_TOA')
  // Select the bands of interest to avoid taking up memory.
  // Filter to get only imagery at a point of interest.
  // Filter to get only six months of data.
  .filterDate('2014-06-01', '2014-12-31')
  // Mask clouds by mapping the cloudMask function over the collection.
  // This will add a cloud score band called 'cloud' to every image.
  .map(function(image) {
    return ee.Algorithms.Landsat.simpleCloudScore(image);

// Convert the collection to an array.
var array = collection.toArray();

// Label of the axes.
var imageAxis = 0;
var bandAxis = 1;

// Get the cloud slice and the bands of interest.
var bands = array.arraySlice(bandAxis, 0, bandNames.length());
var clouds = array.arraySlice(bandAxis, bandNames.length());

// Sort by cloudiness.
var sorted = bands.arraySort(clouds);

// Get the least cloudy images, 20% of the total.
var numImages = sorted.arrayLength(imageAxis).multiply(0.2).int();
var leastCloudy = sorted.arraySlice(imageAxis, 0, numImages);

// Get the mean of the least cloudy images by reducing along the image axis.
var mean = leastCloudy.arrayReduce({
  reducer: ee.Reducer.mean(),
  axes: [imageAxis]

// Turn the reduced array image into a multi-band image for display.
var meanImage = mean.arrayProject([bandAxis]).arrayFlatten([bandNames]);
Map.centerObject(roi, 12);
Map.addLayer(meanImage, {bands: ['B5', 'B4', 'B2'], min: 0, max: 0.5});

As in the linear modeling example, separate the bands of interest from the sort index using arraySlice() along the band axis. Then sort the bands of interest by the cloud index using arraySort(). After the pixels have been sorted by ascending cloudiness, use arraySlice() along the imageAxis to get 20% of the least cloudy pixels. Lastly, apply arrayReduce() along the imageAxis with a mean reducer to get the mean of the least cloudy pixels. The final step converts the array image back to a multi-band image for display.