有没有比这更好的方法在javascript中实现函数式递归findById?

有没有比这更好的方法在javascript中实现函数式递归findById?,javascript,functional-programming,Javascript,Functional Programming,我不喜欢循环,但是这似乎很容易用循环解决,而且很难使用函数编程。以下是循环版本: for(var i = 0; i < collection.length; i++) { var result = collection[i].findById(id); if (result) { return result; } } 这不仅很难看,而且在第一个元素返回truthy之后,当它可以返回时,它会在集合的每个元素上调用findById 您如何实现这一点?如

我不喜欢循环,但是这似乎很容易用循环解决,而且很难使用函数编程。以下是循环版本:

for(var i = 0; i < collection.length; i++) {
    var result = collection[i].findById(id);
    if (result) {
        return result;
    }
}
这不仅很难看,而且在第一个元素返回truthy之后,当它可以返回时,它会在集合的每个元素上调用findById

您如何实现这一点?

如何:

_.find(collection, function(c) {
  return c.findById(id) === true;
});
如果要使用纯javascript:

function findFirstById(collection, id, pos) {
  pos = (typeof pos === 'undefined') ? 0 : pos;
  if (pos >= collection.length)
    return false;
  var result = collection[pos].findById(id);
  if (result)
    return result;
  else
    return findFirstById(collection, id, pos + 1);
}

这对你有帮助吗?

嗯,这没什么好处,但我想你可以用
一些
来实现短循环。有点忽略了使用函数构造使事情更可读的意义,但它应该可以工作

var result;
collection.some(function(datum){
    return (result = datum.findById(id)) || return result == true;
});
ES7规范中还有
find
。当您有此功能可用时,您将能够执行以下操作:

collection.find(function(datum){
    return datum.findById(id) !== null;
});

如果你有这两个功能

let uncurry = f => (x,y) => f(x)(y);
let reduce = f => i => xs => xs.reduce(uncurry(f), i);
您可以编写一个简单的
findById

let findById = id => reduce(y => x => y || x.findById(id))(null);
像这样使用它

findById(15)(collection); // => result | null
它仍将在集合中的每个项目上迭代,但它是并且只会调用
findById
,直到找到结果为止


这是ES5

var uncurry = function uncurry(f) {
  return function (x, y) {
    return f(x)(y);
  };
};
var reduce = function reduce(f) {
  return function (i) {
    return function (xs) {
      return xs.reduce(uncurry(f), i);
    };
  };
};

var findById = function findById(id) {
  return reduce(function (y) {
    return function (x) {
      return y || x.findById(id);
    };
  })(null);
};

如果您想使用下划线/lodash,可以使用

let findById = id => xs =>
  _.reduce(xs, (result, x) => result || x.findById(id), null);

如果
.some()
将从其谓词返回真实值,这会有所帮助,但它不会:(那么u.find()?u.find()将返回元素,而不是findById的结果):/我喜欢这样,我可能会使用
.reduce(collection,(result,x)=>result | | x.findById(id),null)
let findById = id => xs =>
  _.reduce(xs, (result, x) => result || x.findById(id), null);