2015-03-08 25 views
1

我想知道如果其可以检索一个javascript对象包含的所有路径检索的对象项路径

实施例:

obj = { 
    prop1 : { 
    x: 19 
    y: 43 
    } 
    prop2 : { 
    another: { 
     here: 1 
    } 
    } 
    prop3: "hello" 
} 

凡其结果将是具有下列元素的数组:

Result: ["prop1.x", "prop1.y", "prop2.another.here", "prop3"] 

这可能吗?

谢谢!

+0

递归迭代? – 2015-03-08 17:56:05

+0

[递归循环一个对象以构建属性列表]的可能的重复(http://stackoverflow.com/questions/15690706/recursively-looping-through-an-object-to-build-a-property-list) – 2015-03-08 17:57:31

回答

3
function flattenKeys(obj, delimiter) { 
    delimiter = delimiter || '.'; 

    return recurse(obj, '', []); 

    function recurse(obj, path, result) { 
     if (typeof obj === "object") { 
      Object.keys(obj).forEach(function (key) { 
       recurse(obj[key], path + delimiter + key, result); 
      }); 
     } else { 
      result.push(path.slice(delimiter.length)); 
     } 
     return result; 
    } 
} 

用作

var obj = { 
    prop1 : { 
    x: 19, 
    y: 43 
    }, 
    prop2 : { 
    another: { 
     here: 1 
    } 
    }, 
    prop3: "hello" 
}; 

flattenKeys(obj); 

// -> ["prop1.x", "prop1.y", "prop2.another.here", "prop3"] 

替代实现无字符串操作:

function flattenKeys(obj, delimiter) { 
    delimiter = delimiter || '.'; 

    return recurse(obj, [], []); 

    function recurse(obj, path, result) { 
     if (typeof obj === "object") { 
      Object.keys(obj).forEach(function (key) { 
       path.push(key); 
       recurse(obj[key], path, result); 
       path.pop(); 
      }); 
     } else { 
      result.push(path.join(delimiter)); 
     } 
     return result; 
    } 
} 
+0

做得好! 一些“基准”:http://jsfiddle.net/jkoudys/w49rcp40/ (可能是错误的:) :) – 2015-03-08 20:52:14

+0

你粘贴了错误的链接?这只是我的jsfiddle。 – 2015-03-08 21:17:50

+0

你是对的,错误的链接:http://jsfiddle.net/w49rcp40/2/。看起来像它的浏览器依赖。他们都很优秀;) – 2015-03-08 21:57:41

2

写到这同时托默勒格在这里放在一起。递归是做这件事的明显方法。

var inputObject = { 
    prop1: { 
     x: 19, 
     y: 43 
    }, 
    prop2: { 
     another: { 
      here: 1 
     } 
    }, 
    prop3: "hello" 
}; 

function getProps(obj) { 
    var props = []; 

    var findPropsRecursive = function (robj, str) { 
    robj = robj || {}; 
    var keys = Object.keys(robj); 
    if (keys.length > 0 && (robj instanceof Object)) { 
     return keys.map(function (key) { 
     return findPropsRecursive(robj[key], str + (str ? '.' : '') + key); 
     }); 
    } else { 
     props.push(str); 
     return ''; 
    } 
    }; 

    findPropsRecursive(obj, ''); 

    return props; 
} 

console.log(getProps(inputObject)); 

上的jsfiddle:http://jsfiddle.net/jkoudys/w49rcp40/

+0

您的代码中存在一个错误,Internet Explorer会显示它:TypeError:Object.keys:参数不是Object。 – Tomalak 2015-03-09 07:19:30

+1

2015-03-09 15:28:28

+0

这就是polyfills的用途。顺便说一句,如果你想要遵循他们的例子,Google应用程序只能为IE提供n-1支持声明,并且由于最新的稳定版本是IE11,所以即使9也不支持。我个人倾向于使用n-2,但是IE8的尺寸已经足够n-3,可以放置'您的浏览器不支持'页面,尽管我通常会等到n-4。 n-3通常只是尽力而为。 – 2015-03-10 01:12:42