I'm currently trying to let JavaScript generate a truth table for a boolean function. Given a function, the code should just list all boolean combina开发者_如何转开发tions possible, with the function output from each combination.
As for generating all combinations, I put this together (simplified to the combinations code only):
var table = [];
function combinations(current) {
var current = current || [];
if(current.length === 3) {
table.push(current);
} else {
var c = copy(current);
c.push(true);
combinations(c);
c = copy(current);
c.push(false);
combinations(c);
}
}
function copy(a) {
var r = [];
for(var i = 0; i < a.length; i++) r.push(a[i]);
return r;
}
combinations(); // now table consists of each pair of 3 boolean values
So basically when it has reached a combination (i.e. current.length === 3
), it pushes a result record to table
. I was wondering, however, whether this is the recommended way of storing results of a recursive function.
I faced the recommendation of using return
inside the recursive function, but how would one implement such a thing - i.e., if combinations
in the end has to return an array containing all elements, how is it possible to do so? I could, of course, just use return table
in the end, but I'm actually looking for a way to do this all inside the function, without an external variable like now.
So, how do I make combinations
return the results as an array without using an external variable?
Use Array.concat()
.
function combinations(current) {
var current = current || [];
if(current.length === 3) {
return [current];
} else {
return combinations(current.concat(true)).concat(combinations(current.concat(false)));
}
}
var table = combinations(); // now table consists of each pair of 3 boolean values
console.log(table);
Much more elegant, no?
Demo →
To avoid polluting the global space you could use a closure to contain your recursive function. There is an excellent writeup of this concept at http://drewwells.net/blog/2010/recursion-in-javascript/.
Your current solution seems fine to me. It might not be the most elegant, but it is simple and does the job (the only ugly bit is the hardcoded 3 - you should turn that into a parameter)
Your real question seems to be more language-agnostic than Javascript. If you want the function to return the combinations, than you can prefectly do so, just clearly have in mind what your function should return and write the base and recursive cases:
function combinations(domain, n){
//returns a list of combinations of length `n` with elements from `domain`
if(n <= 0){
return [[]]; //the empty combination is the only solution
}else{
var small_combs = combinations(domain, n-1);
var big_combs = [];
for(var i=0; i<domain.length; i++){
for(var j=0; j<small_combs.length; j++){
big_combs.push(small_combs[j].concat(domain[i]))
}
}
return big_combs;
}
}
table = combinations([true, false], 3);
var id = { "object": "page", "entry": [{ "id": "1588811284674233", "time": 1511177084837, "messaging": [{ "sender": { "id": "1393377930761248" }, "recipient": { "id": "1588811284674233" }, "timestamp": 1511177084553, "message": { "mid": "mid.$cAAX_9pLcfu1mCnGmiVf2Sxd2erI2", "seq": 1882, "text": "a" } }] }] };
function getKey(obj, data) {
var data = data || [];
if (obj) {
var keys = Object.keys(obj);
for (var pos in keys) {
console.log();
data.push(keys[pos]);
if ((obj[keys[pos]].constructor === Array)) {
for (var i = 0; i < obj[keys[pos]].length; i++) {
getKey(obj[keys[pos]][i], data);
}
}
else if (obj[keys[pos]].constructor === Object) {
getKey(obj[keys[pos]], data);
}
}
return data;
}
}
精彩评论