Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
599 views
in Technique[技术] by (71.8m points)

recursion - find possible paths in map : recursive function in javascript

doc = {
  'a': {
    'b': {
      'c': 'hello'
    },
    'd': {
      'c': 'sup',
      'e': {
        'f': 'blah blah blah'
      }
    }
  }
}

function get(json, path) {
  var str = path.split('.');
  var temp = json;
  var arr = [];
  var keystr = "";
  for (var i = 0; i < str.length; i++) {
    if (str[i] != "*") {

      keystr += str[i] + ".";

      if (temp[str[i]] === undefined)
        break;
      else {
        temp = temp[str[i]];
        if (i == str.length - 1) {
          var nObj = {};
          nObjKey = keystr.substr(0, keystr.length - 1);
          nObj[nObjKey] = temp
            // console.log("Obj check" + JSON.stringify(nObj) + keystr)
          arr.push(nObj);
        }
      }
    } else {
      for (var key in temp) {
        var concat = key + "."
        for (var j = i + 1; j < str.length; j++)
          concat += str[j] + ".";
        if (temp[key] !== undefined && temp[key] instanceof Object) {

          var m = keystr + concat.substr(0, concat.length - 1);
          var obj = (get(temp, concat.substr(0, concat.length - 1)));

          if (obj != "") {
            // console.log("existing arr "+JSON.stringify(arr))
            obj[m] = (obj[0])[concat.substr(0, concat.length - 1)]
              //  console.log("hello "+JSON.stringify(obj) + " end hello")
            arr.push(obj);
          }
        } else if (temp[key] !== undefined && i == str.length - 1) {
          // arr.push(temp);
        }
      }
    }
  }
  return arr;
}

var result = (get(doc, 'a.*.e'))
console.log(result)
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You could change the structure of the operation a little bit with a recursive approach and an exit early exit often paradigm with checking of single parts with exit options, like

  • length, a part result is found,
  • falsy or not object types,
  • part at index is a star, then iterate all keys from the object, or
  • the part at index is a key, then call the function again.

At the end, with a found path, joint the path and generate a new property with the actual value of the object.

function get(object, path) {

    function iter(o, p, i) {
        if (i === parts.length) {
            result[p.join('.')] = o;
            return;
        }
        if (!o || typeof o !== 'object') {
            return;
        }
        if (parts[i] === '*') {
            Object.keys(o).forEach(function (k) {
                iter(o[k], p.concat(k), i + 1);
            });
            return;
        }
        if (parts[i] in o) {
            iter(o[parts[i]], p.concat(parts[i]), i + 1);
        }
    }

    var result = {},
        parts = path.split('.');

    iter(object, [], 0);
    return result;
}

var doc = { a: { b: { c: 'hello' }, d: { c: 'sup', e: { f: 'blah blah blah' } } } };

console.log(get(doc, 'a.*.e'));
console.log(get(doc, 'a.*.c'));
.as-console-wrapper { max-height: 100% !important; top: 0; }

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...