UNPKG

shaka-player

Version:
180 lines (157 loc) 3.94 kB
/*! @license * Shaka Player * Copyright 2016 Google LLC * SPDX-License-Identifier: Apache-2.0 */ goog.provide('shaka.util.ArrayUtils'); /** * @namespace shaka.util.ArrayUtils * @summary Array utility functions. */ shaka.util.ArrayUtils = class { /** * Returns whether the two values contain the same value. This correctly * handles comparisons involving NaN. * @param {T} a * @param {T} b * @return {boolean} * @template T */ static defaultEquals(a, b) { // NaN !== NaN, so we need to special case it. if (typeof a === 'number' && typeof b === 'number' && isNaN(a) && isNaN(b)) { return true; } return a === b; } /** * Remove given element from array (assumes no duplicates). * @param {!Array<T>} array * @param {T} element * @template T */ static remove(array, element) { const index = array.indexOf(element); if (index > -1) { array.splice(index, 1); } } /** * Count the number of items in the list that pass the check function. * @param {!Array<T>} array * @param {function(T):boolean} check * @return {number} * @template T */ static count(array, check) { let count = 0; for (const element of array) { count += check(element) ? 1 : 0; } return count; } /** * Determines if the given arrays contain equal elements in any order. * * @param {!Array<T>} a * @param {!Array<T>} b * @param {function(T, T):boolean=} compareFn * @return {boolean} * @template T */ static hasSameElements(a, b, compareFn) { if (!compareFn) { compareFn = shaka.util.ArrayUtils.defaultEquals; } if (a.length != b.length) { return false; } const copy = b.slice(); for (const item of a) { const idx = copy.findIndex((other) => compareFn(item, other)); if (idx == -1) { return false; } // Since order doesn't matter, just swap the last element with // this one and then drop the last element. copy[idx] = copy[copy.length - 1]; copy.pop(); } return copy.length == 0; } /** * Partitions an array into two arrays based on a predicate. * Returns [matching, notMatching]. * * @param {!Array<T>} array * @param {function(T):boolean} predicate * @return {!Array<!Array<T>>} * @template T */ static partition(array, predicate) { const yes = []; const no = []; for (const element of array) { if (predicate(element)) { yes.push(element); } else { no.push(element); } } return [yes, no]; } /** * Returns the index of the first element for which `predicate` returns * false. Assumes the array is partitioned so that predicate returns true * for a contiguous prefix followed by all-false (i.e. a standard * lower-bound / partition-point binary search). * * @param {!Array<T>} array * @param {function(T):boolean} predicate * @return {number} * @template T */ static binarySearch(array, predicate) { let lo = 0; let hi = array.length; while (lo < hi) { const mid = (lo + hi) >>> 1; if (predicate(array[mid])) { lo = mid + 1; } else { hi = mid; } } return lo; } /** * Determines if the given arrays contain equal elements in the same order. * * @param {Array<T>} a * @param {Array<T>} b * @param {function(T, T):boolean=} compareFn * @return {boolean} * @template T */ static equal(a, b, compareFn) { if (a === b) { return true; } if (!a || !b) { return a == b; } if (!compareFn) { compareFn = shaka.util.ArrayUtils.defaultEquals; } if (a.length != b.length) { return false; } for (let i = 0; i < a.length; i++) { if (!compareFn(a[i], b[i])) { return false; } } return true; } };