当前位置: 代码迷 >> JavaScript >> 使用循环创建对象链接
  详细解决方案

使用循环创建对象链接

热度:10   发布时间:2023-06-05 16:01:10.0

有没有办法从循环创建链式对象? 例如输入:

["table1","table2","table3"]

输出:

  db
  .select(fields)
  .from(table)
  .innerJoin("table1")
  .innerJoin("table2")
  .innerJoin("table3")

另一个输入:

 ["table1","table2","table3","table4","table5"]

输出:

  db
  .select(fields)
  .from(table)
  .innerJoin("table1")
  .innerJoin("table2")
  .innerJoin("table3")
  .innerJoin("table4")
  .innerJoin("table5")

现在我不知道怎么做,除了使用eval,这不是我想做的事情。

我需要这个使用knex加入多个表,所以如果有其他方法这样做,我会很高兴:)

链接的工作方式是每个方法都返回一个对象,该对象将下一个方法作为属性。 这意味着您可以使用类的东西来继续调用从前一个返回的对象的下一个方法。

reduce()接受一个初始对象,你可以传递它以使事情滚动。 就像是:

var tables = ["table1","table2","table3"]
let res = tables.reduce((res, table) => res.innerJoin(table), db.select(fields).from(table))

为了理解这是如何工作的,我们可以创建一个假的db对象,其中包含返回链中下一个方法的对象的所有方法。 innerJoin方法只是将参数添加到value属性:

 // fake db object with these methods const db = { select(t) { this.val = [] // initialize val return this }, from(t) { return this }, innerJoin(name) { this.val.push("Added: " + name) return this } } var tables = ["table1","table2","table3"] // call innerjoin for each of the tables // this is the same as chaining them let res = tables.reduce((res, table) => res.innerJoin(table), db.select().from()) // values where accumlated in the val property console.log(res.val) 

我认为研究函数式编程会对你有所帮助。

我在下面的互联网链接中使用了管道功能,但您可以使用lodash / Ramda / underscore或者您喜欢的任何库。

我在这里使用的两个主要概念是currying和piping。

Currying是当你分解一个函数时,它将多个参数带入一系列参数中,这些函数接受参数的一部分,我们也在使用curring,它从另一个函数返回一个函数来组成新函数。

管道功能需要一系列操作; 每个操作都参与其中; 处理它; 并将处理后的输出作为序列中下一个操作的输入。 管道功能的结果是一个功能,它是操作序列的捆绑版本。

我们在这里做的是获取一个数组,创建一个我们想要应用于值的新函数数组。

所以我们想在db上加载一个连接。

join => con => con.innerJoin(join);

正在取一个值,即“table1”并返回一个函数,该函数接受一个调用连接的db连接并返回下一个连接。

const joins = toJoin.map(join => con => con.innerJoin(join)); 这创建了传递给管道的函数数组。

 const db = ({ select: function (field) { console.log('select', field) return db }, from: function (table) { console.log('from', table) return db; }, innerJoin: function (join) { console.log('innerJoin', join) return db; } }); const _pipe = (a, b) => (arg) => b(a(arg)); const pipe = (args) => [].slice.apply(args).reduce(_pipe); function joinInnerMultiple(table, fields, toJoin) { const joins = toJoin.map(join => con => con.innerJoin(join)); return pipe(joins)(db.select(fields).from(table)); } joinInnerMultiple("User", "uuid", ["table1", "table2", "table3", "table4", "table5"]) 

  相关解决方案