Returns a new array, with each element in the original array satisfying the
    passed-in predicate set to `new_value`

    Args:
        array (WeldObject / Numpy.ndarray): Input array
        predicates (WeldObject / Numpy.ndarray<bool>): Predicate set
        ty (WeldType): Type of each element in the input array

    Returns:
        A WeldObject representing this computation

def pivot_filter(pivot_array, predicates, ty=None):
    """
    Returns a new array, with each element in the original array satisfying the
    passed-in predicate set to `new_value`

    Args:
        array (WeldObject / Numpy.ndarray): Input array
        predicates (WeldObject / Numpy.ndarray<bool>): Predicate set
        ty (WeldType): Type of each element in the input array

    Returns:
        A WeldObject representing this computation
    """
    weld_obj = WeldObject(encoder_, decoder_)

    pivot_array_var = weld_obj.update(pivot_array)
    if isinstance(pivot_array, WeldObject):
        pivot_array_var = pivot_array.obj_id
        weld_obj.dependencies[pivot_array_var] = pivot_array

    predicates_var = weld_obj.update(predicates)
    if isinstance(predicates, WeldObject):
        predicates_var = predicates.obj_id
        weld_obj.dependencies[predicates_var] = predicates

    weld_template = """
    let index_filtered =
      result(
        for(
          zip(%(array)s.$0, %(predicates)s),
          appender,
          |b, i, e| if (e.$1, merge(b, e.$0), b)
        )
      );
    let pivot_filtered =
      map(
        %(array)s.$1,
        |x|
          result(
            for(
              zip(x, %(predicates)s),
              appender,
              |b, i, e| if (e.$1, merge(b, e.$0), b)
            )
          )
      );
    {index_filtered, pivot_filtered, %(array)s.$2}
    """
    weld_obj.weld_code = weld_template % {
        "array": pivot_array_var,
        "predicates": predicates_var}

    return weld_obj