Skip to main content

JavaScript function to partition an object given a predicate. All elements satisfying the predicate are part of the first returned object, and all elements that don't are in the second.

/**
 * Copyright 2015-present Facebook. All Rights Reserved.
 *
 * @typechecks
 *
 */

"use strict";

var hasOwnProperty = Object.prototype.hasOwnProperty;

/**
 * Executes the provided `callback` once for each enumerable own property in the
 * object. The `callback` is invoked with three arguments:
 *
 *  - the property value
 *  - the property name
 *  - the object being traversed
 *
 * Properties that are added after the call to `forEachObject` will not be
 * visited by `callback`. If the values of existing properties are changed, the
 * value passed to `callback` will be the value at the time `forEachObject`
 * visits them. Properties that are deleted before being visited are not
 * visited.
 *
 * @param {?object} object
 * @param {function} callback
 * @param {*} context
 */
function forEachObject(object, callback, context) {
    for (var name in object) {
        if (hasOwnProperty.call(object, name)) {
            callback.call(context, object[name], name, object);
        }
    }
}

/**
 * Partitions an object given a predicate. All elements satisfying the predicate
 * are part of the first returned object, and all elements that don't are in the
 * second.
 */
function partitionObject(object, callback, context) {
    var first = {};
    var second = {};
    forEachObject(object, function(value, key) {
        if (callback.call(context, value, key, object)) {
            first[key] = value;
        } else {
            second[key] = value;
        }
    });
    return [first, second];
}

/**
 * Partitions the enumerable properties of an object into two objects, given a
 * whitelist `Set` for the first object. This is comparable to
 * `whitelistObjectKeys`, but eventually keeping all the keys. Returns a tuple
 * of objects `[first, second]`.
 */
function partitionObjectByKey(source, whitelist) {
    return partitionObject(source, function(_, key) {
        return whitelist.has(key);
    });
}

// module.exports = partitionObject;
// module.exports = partitionObjectByKey;