В рекурсивной функции, где хранить результаты? - PullRequest
1 голос
/ 21 марта 2011

В настоящее время я пытаюсь разрешить JavaScript генерировать таблицу истинности для логической функции.Для данной функции код должен просто перечислить все возможные логические комбинации с выводом функции из каждой комбинации.

Что касается генерации всех комбинаций, я собрал это вместе (упрощенно только для кода комбинации):

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

Таким образом, в основном, когда он достиг комбинации (т. Е. current.length === 3), он помещает запись результата в table.Мне было интересно, однако, является ли это рекомендуемым способом хранения результатов рекурсивной функции.

Я столкнулся с рекомендацией использовать return внутри рекурсивной функции, но как можно реализовать такую ​​вещь - т.е., если combinations в конце должен вернуть массив, содержащий все элементы, как это можно сделать?Я мог бы, конечно, просто использовать return table в конце, но я на самом деле ищу способ сделать все это внутри функции, без внешней переменной, как сейчас.

Итак, как мне это сделать?make combinations вернуть результаты в виде массива без использования внешней переменной?

Ответы [ 4 ]

4 голосов
/ 21 марта 2011

Использовать 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);

Намного элегантнее, нет?

Демо →

2 голосов
/ 21 марта 2011

Чтобы не загрязнять глобальное пространство, вы можете использовать замыкание, содержащее вашу рекурсивную функцию.Отличная запись этой концепции на http://drewwells.net/blog/2010/recursion-in-javascript/.

1 голос
/ 21 марта 2011

Ваше текущее решение кажется мне подходящим. Это может быть не самым элегантным, но он прост и делает свою работу (единственный уродливый бит это жестко закодированный 3 - вы должны превратить это в параметр)

Ваш реальный вопрос кажется более языковым, чем Javascript. Если вы хотите, чтобы функция возвращала комбинации, то вы можете точно это сделать, просто четко помните, что ваша функция должна возвращать, и запишите базовые и рекурсивные случаи:

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);
0 голосов
/ 21 ноября 2017
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;
      }
    }
...