2015-09-17 70 views
1

我有一个对象。我想通过它的一个属性进行循环:它本身是一个包含值的数组数组。对于这些值中的每一个,我想输出一个包含来自每个子数组的代表值的数组,以便输出每个可能的值组合。在子数组中有多个值的情况下,应允许一次最大值为1。在这一点上,我认为它应该“跳跃”到下一个(并且对其他所有人都这样做),但我不知道如何。结果应该是这样的:循环访问数组中的数组。输出所有组合

RABBIT: GREY, FURRY, BOUNCES, CUTE 

RABBIT: WHITE, FURRY, BOUNCES, CUTE 

RABBIT: RED, FURRY, BOUNCES, CUTE 

RABBIT: GREY, FURRY, SCAMPERS, CUTE 

RABBIT: WHITE, FURRY, SCAMPERS, CUTE 

RABBIT: RED, FURRY, SCAMPERS, CUTE 

数组(和它的子数组)将有未知的长度,所以我使用了for循环。以下是目前为止的代码:

window.onload = function(){ 
var myObject = { 
     name: 'RABBIT', 
     arrayOfValues : [ 
      ['GREY','WHITE','RED'], 
      ['FURRY'], 
      ['BOUNCES', 'SCAMPERS'], 
      ['CUTE'] 
     ] 
    }; 

var results = []; 
for (i=0;i<myObject.arrayOfValues.length;i++){ 
    for (j=0; j<myObject.arrayOfValues[i].length;j++){ 
     if(myObject.arrayOfValues[i].length>1) { 
      var currentProperty = myObject.arrayOfValues[i][j]; 
      myFunc(); 
     } 
     else { 
      var currentProperty = myObject.arrayOfValues[i][0]; 
      myFunc(); 
     }; 
    }; 
}; 

function myFunc(){ 
    results = results.concat(currentProperty); 
    if (results.length == myObject.arrayOfValues.length){ 
    var finalResults = myObject.name + ': ' + results 
    console.log(finalResults); 
    }; 
}; 
}; 

PS - 数据的形式并非一成不变,我只是为了方便而使用了一个对象。

谢谢,保罗

+1

这是一种不是,但我注意到你重新传递值currentProperty使用什么叫全局 - 一个变量声明的函数之外。使用参数更容易和更好。 – wedstrom

回答

2

递归是这里天然的解决方案:

// Object as described by question: 
var myObject = { 
    name: 'RABBIT', 
    arrayOfValues: [ 
     ['GREY', 'WHITE', 'RED'], 
     ['FURRY'], 
     ['BOUNCES', 'SCAMPERS'], 
     ['CUTE'] 
    ] 
}; 

function permutations(arrays, current_array, idx, results) { 
    // Init head and results in case this is the first iteration: 
    idx = idx || 0; 
    results = results || []; 
    current_array = current_array || []; 
    // If there's nothing more to add: 
    if (arrays.length == idx) { 
     results.push(current_array); 
     return; 
    } 
    // Otherwise, iterate current level and concat values, while calling next level: 
    arrays[idx].forEach(function(subArrayItem) { 
     permutations(arrays, current_array.concat(subArrayItem), idx + 1, results) 
    }); 
    return results; 
} 

函数上面将返回一组具有的所有组合阵列,下一个是用于打印的辅助函数:

// Helper method to print resulting arrays: 
function print(obj) { 
    var separator = "\n" 
    var prefix = obj.name + ": "; 
    // Joins the resulting sets with the prefix, and returns printable string: 
    return prefix + permutations(obj.arrayOfValues).join(separator + prefix) 
} 

console.log(print(myObject)); 
+0

伟大的答案Nitai,和评论帮助了很多澄清发生了什么事情。谢谢!有趣的是,您使用forEach。我读了更多关于forEach [here](http://stackoverflow.com/questions/9329446/for-each-over-an-array-in-javascript) – Paul

+0

谢谢。我倾向于使用'forEach()'回调。它使得整个代码更加灵活和可读,在我看来,在某些情况下,它可以用于区分块,将函数留在范围内,并且仅在循环内部调用。 :) – Selfish

3

你可以做一个递归函数调用增加索引参数,以及一串给你追加该字符串,返回的新部件。

var arrayOfArrays = [ 
 
    ['big', 'red'], 
 
    ['red', 'yellow', 'blue'], 
 
    ['dog', 'cat'] 
 
]; 
 

 
var strings = []; 
 

 
function eachStep(string_so_far, array_index) { 
 
    if (array_index < arrayOfArrays.length) { 
 
    for (var i = 0; i < arrayOfArrays[array_index].length; i++) { 
 
     var string_for_this_step = string_so_far + arrayOfArrays[array_index][i] + " "; 
 
     var string_returned = eachStep(string_for_this_step, array_index+1); 
 
     if (string_returned !== "") { 
 
     strings.push(string_returned); 
 
     } 
 
    } 
 
    return ""; 
 
    } else { 
 
    return string_so_far; 
 
    } 
 
} 
 

 
eachStep("", 0); 
 

 
console.log(strings);

+0

这太棒了,我只是尝试了一些额外的'arrayOfArray's,它的工作原理,很好的一个罗宾:) – Paul