FindViaPredicate.js 1.3 KB

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