function filterBy(arr, search) {
  var arr = src_util.convertArray(arr);

  if (search == null) {
    return arr;
  }

  if (typeof search === 'function') {
    return arr.filter(search);
  } // cast to lowercase string


  search = ('' + search).toLowerCase();
  var n = 2; // extract and flatten keys

  var keys = Array.prototype.concat.apply([], src_util.toArray(arguments, n));
  var res = [];
  var item, key, val, j;

  for (var i = 0, l = arr.length; i < l; i++) {
    item = arr[i];
    val = item && item.$value || item;
    j = keys.length;

    if (j) {
      while (j--) {
        key = keys[j];

        if (key === '$key' && contains(item.$key, search) || contains(src_util.getPath(val, key), search)) {
          res.push(item);
          break;
        }
      }
    } else if (contains(item, search)) {
      res.push(item);
    }
  }

  return res;
}
Filter filter for arrays

@param {Array} arr
@param {String} prop
@param {String|Number} search