FindViaPredicate.js 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142
  1. 'use strict';
  2. var $TypeError = require('es-errors/type');
  3. var Call = require('./Call');
  4. var Get = require('./Get');
  5. var ToBoolean = require('./ToBoolean');
  6. var IsCallable = require('./IsCallable');
  7. var ToString = require('./ToString');
  8. var Type = require('./Type');
  9. var isInteger = require('../helpers/isInteger');
  10. module.exports = function FindViaPredicate(O, len, direction, predicate, thisArg) {
  11. if (Type(O) !== 'Object') {
  12. throw new $TypeError('Assertion failed: Type(O) is not Object');
  13. }
  14. if (!isInteger(len) || len < 0) {
  15. throw new $TypeError('Assertion failed: len must be a non-negative integer');
  16. }
  17. if (direction !== 'ascending' && direction !== 'descending') {
  18. throw new $TypeError('Assertion failed: direction must be "ascending" or "descending"');
  19. }
  20. if (!IsCallable(predicate)) {
  21. throw new $TypeError('predicate must be callable'); // step 1
  22. }
  23. for ( // steps 2-4
  24. var k = direction === 'ascending' ? 0 : len - 1;
  25. direction === 'ascending' ? k < len : k >= 0;
  26. k += 1
  27. ) {
  28. var Pk = ToString(k); // step 4.a
  29. var kValue = Get(O, Pk); // step 4.c
  30. var testResult = Call(predicate, thisArg, [kValue, k, O]); // step 4.d
  31. if (ToBoolean(testResult)) {
  32. return { '[[Index]]': k, '[[Value]]': kValue }; // step 4.e
  33. }
  34. }
  35. return { '[[Index]]': -1, '[[Value]]': void undefined }; // step 5
  36. };