简体   繁体   English

递归 flatMap

[英]Recursive flatMap

I'm trying to figure out how to convert the following javascript function into a dynamic function that will perform the flapMap recursively.我试图弄清楚如何将以下 javascript 函数转换为一个动态函数,该函数将递归地执行flapMap。

 function getPermutations(object) { let array1 = object[0].options, array2 = object[1].options, array3 = object[2].options; return array1.flatMap(function(array1_item) { return array2.flatMap(function(array2_item) { return array3.flatMap(function(array3_item) { return array1_item + ' ' + array2_item + ' ' + array3_item; }); }); }); } let object = [{ "options": ['blue', 'gray', 'green'] }, { "options": ['large', 'medium', 'small'] }, { "options": ['wood', 'steel', 'pastic'] }]; console.log('Permutations', getPermutations(object));

In the example, I'm sending 3 arrays into the function which is why it has 3 iterations of flapMap.在这个例子中,我将 3 个数组发送到函数中,这就是为什么它有 3 次flapMap 迭代。 Works fine, but I am trying to make it dynamic, so I can pass a dynamic array and the function would do the flapMap recursively depending on the array.工作正常,但我试图使它成为动态的,所以我可以传递一个动态数组,并且该函数将根据数组递归地执行flapMap。

In your example you kept track of array1_item , array2_item and co in their individual variables.在您的示例中,您在各自的变量中跟踪了array1_itemarray2_item和 co 。 You can move them to an array (having dynamic size; I called it _prevItems ) and pass them as an parameter to the recursive call.您可以将它们移动到一个数组(具有动态大小;我称之为_prevItems )并将它们作为参数传递给递归调用。

 function getPermutations(objects, _prevItems = []) { // join the items at the end of the recursion if (objects.length === 0) return _prevItems.join(' ') // call again with all but the first element, and add the current item to _prevItems return objects[0].flatMap(item => getPermutations(objects.slice(1), [..._prevItems, item])) } let objects = [['blue', 'gray', 'green'], ['large', 'medium', 'small'], ['wood', 'steel', 'pastic']]; console.log('Permutations', getPermutations(objects));

One way to do this is with reduce .一种方法是使用reduce

You want to reduce the list of options to one list of permutations.您想将选项列表减少到一个排列列表。

 function getPermutations(list) { return ( list // First map to list of options (list of list of strings) .map((item) => item.options) // Then reduce. Do not set any initial value. // Then the initial value will be the first list of options (in // our example, ["blue", "gray", "green"]) .reduce((permutations, options) => { return permutations.flatMap((permutation) => options.map((option) => permutation + " " + option) ); }) ); } // Renamed this to list, since it is an array and not an object const list = [ { options: ["blue", "gray", "green"] }, { options: ["large", "medium", "small"] }, { options: ["wood", "steel", "pastic"] }, ]; console.log("Permutations", getPermutations(list));

Edit: I know you asked for recursion.编辑:我知道你要求递归。 If this is a school task, then perhaps you have to use recursion, but otherwise I would recommend avoiding recursion when possible, since it tends to make things more complicated.如果这是一项学校任务,那么也许您必须使用递归,否则我建议尽可能避免递归,因为它往往会使事情变得更加复杂。 (Of course, this is a general rule, and like all rules it has some exceptions.) (当然,这是一般规则,与所有规则一样,它也有一些例外。)

you can flatMap two arrays at a time using the recursive bottom up approach and build your string from the end您可以使用递归自底向上方法一次 flatMap 两个数组,并从最后构建您的字符串

const getPermutations = (array) => {
  if(array.length === 1)
     return array[0].options;

  const prefixItems = array[0].options;
  const suffixItems = getPermutations(array.slice(1));

  return prefixItems.flatMap(prefix => {
    return suffixItems.flatMap(suffix => {
      return prefix + ' ' + suffix
    });
  })
}

You can use recursion to make your function dynamic.您可以使用递归使您的函数动态化。 my solution is that, you need to make a function with three argument (array, index, result), call you function over and over again until you finished iterating all you array object.我的解决方案是,您需要创建一个带有三个参数(数组、索引、结果)的函数,一遍又一遍地调用您的函数,直到您完成对所有数组对象的迭代。 for the example:例如:

 function getPermutations(array, index = 0, prev = "") { // if the current index is lower than array length, keep calling the function if (index < array.length - 1) { return array[index].options.flatMap(item => { // if the previous value is empty, send the current item const current = prev ? `${prev} ${item}` : item; // resend the current value for the next iteration return getPermutations(array, index + 1, current); }); } else { // end of the iteration return array[index].options.flatMap(item => `${prev} ${item}`); } } let object = [{ "options": ['blue', 'gray', 'green'] }, { "options": ['large', 'medium', 'small'] }, { "options": ['wood', 'steel', 'pastic'] }]; console.log('Permutations', getPermutations(object));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM