经过多次尝试和搜索,我决定问,因为我卡住了。我有一个这样的txt文件:
CITYS
CITYS.AREAS
CITYS.AREAS.STREETS
CITYS.AREAS.STREETS.HOUSES
CITYS.AREAS.STREETS.HOUSES.ROOMS
CITYS.AREAS.STREETS.HOUSES.ROOMS.KITCHEN
CITYS.AREAS.STREETS.HOUSES.ROOMS.LIVINGROOMS
CITYS.AREAS.STREETS.HOUSES.ROOMS.LIVINGROOMS.TV
CITYS.AREAS.STREETS.HOUSES.ROOMS.LIVINGROOMS.TABLE
CITYS.AREAS.STREETS.HOUSES.ROOMS.LIVINGROOMS.TABLE.VASE
CITYS.AREAS.STREETS.HOUSES.ROOMS.LIVINGROOMS.TABLE.ASTREY
CITYS.AREAS.STREETS.HOUSES.ROOMS.BATHROOMS
CITYS.AREAS.STREETS.HOUSES.ROOMS.BATHROOMS.BATHTUBE
CITYS.AREAS.STREETS.HOUSES.ROOMS.BATHROOMS.BATHTUBE.SHAMPOO
CITYS.AREAS.STREETS.HOUSES.ROOMS.BATHROOMS.BATHTUBE.CONTITIONER
CITYS.AREAS.STREETS.HOUSES.GARDEN
CITYS.AREAS.STREETS.HOUSES.GARDEN.POOL
CITYS.AREAS.STREETS.HOUSES.GARDEN.POOL.WATER
CITYS.AREAS.STREETS.HOUSES.GARDEN.TREE.....
CITYS.AREAS.STREETS.CARS
CITYS.AREAS.STREETS.CARS.BRAND...
CITYS.AREAS.STREETS.CARS.BRAND.LOGO.....
CITYS.AREAS.STREETS.CARS.COLOR..
CITYS.AREAS.STREETS.CARS.TYPE..
<小时/> 我想将它转换为嵌套对象,如
CITYS:{
AREAS:{
STREETS:{
HOUSES:{
ROOMS: {
LIVINGROOMS: {TV,TABLE:{VASE,ASTREY}},
BATHROOMS: {BATHTUBE:{SHAMPOO,CONTITIONER},MIRROR},
...
},
GARDEN:{
......
},
},
CARS:{
BRAND:{LOGO},
COLOR:{},
TYPE:{},
......
},
},
}
}
<小时/> 我想做那样的事情(在阵列中)
for(var line = 0; line < lines.length; line++){
var n = lines[line];
var ninpieces = n.split(".");
var name=ninpieces[ninpieces.length-1];
var nametostore=ninpieces[ninpieces.length-2] ;
CreateObject(name,nametostore);
};
CreateObject=function(name,nametostore){
this.a= name;
this.b= nametostore;
newpar=this['b'];
newchild=this['a'];
this[newchild]=new Array();
if (typeof this[newpar] != "object") {
this[newpar]=new Array();
}
this[newchild].push(name);
this[newpar].push(this[newchild])
stractureobj.push(this[newpar])
}
我在stackoverflow中找到的东西组合但它不起作用。
答案 0 :(得分:0)
您可以使用String.prototype.split()
RegExp
/\n/
作为参数,将文本文件拆分为换行符Array.prototype.filter()
的新行字符Boolean
,以删除空白项目阵列;将stractureobj
设置为空对象;使用单个for
循环Array.prototype.reduce()
来设置stractureobj
for (var line = 0
, stractureobj = {}
, lines = textFileContents.split(/\n/).filter(Boolean)
; line < lines.length
; line++) {
var n = lines[line];
if (line === 0) {
stractureobj[lines[line]] = {}
} else {
var ninpieces = n.split(/\./).filter(Boolean);
ninpieces.reduce(function(obj, prop, index) {
var curr = ninpieces[index + 1];
if (!obj[prop] && !!curr) {
obj[prop] = {
[curr]: {}
};
} else {
if (obj[prop] && curr
&& !obj[prop][curr]) {
obj[prop][curr] = {}
}
}
return obj[prop]
}, stractureobj)
}
};
for (var line = 0
, stractureobj = {}
, lines = document.querySelector("pre")
.textContent.split(/\n/).filter(Boolean)
; line < lines.length
; line++) {
var n = lines[line];
if (line === 0) {
stractureobj[lines[line]] = {}
} else {
var ninpieces = n.split(/\./).filter(Boolean);
ninpieces.reduce(function(obj, prop, index) {
var curr = ninpieces[index + 1];
if (!obj[prop] && !!curr) {
obj[prop] = {
[curr]: {}
};
} else {
if (obj[prop] && curr && !obj[prop][curr]) {
obj[prop][curr] = {}
}
}
return obj[prop]
}, stractureobj)
}
};
document.querySelectorAll("pre")[1].textContent = JSON.stringify(stractureobj, null, 2)
&#13;
pre:nth-of-type(1) {
display: none;
}
&#13;
<pre>CITYS
CITYS.AREAS
CITYS.AREAS.STREETS
CITYS.AREAS.STREETS.HOUSES
CITYS.AREAS.STREETS.HOUSES.ROOMS
CITYS.AREAS.STREETS.HOUSES.ROOMS.KITCHEN
CITYS.AREAS.STREETS.HOUSES.ROOMS.LIVINGROOMS
CITYS.AREAS.STREETS.HOUSES.ROOMS.LIVINGROOMS.TV
CITYS.AREAS.STREETS.HOUSES.ROOMS.LIVINGROOMS.TABLE
CITYS.AREAS.STREETS.HOUSES.ROOMS.LIVINGROOMS.TABLE.VASE
CITYS.AREAS.STREETS.HOUSES.ROOMS.LIVINGROOMS.TABLE.ASTREY
CITYS.AREAS.STREETS.HOUSES.ROOMS.BATHROOMS
CITYS.AREAS.STREETS.HOUSES.ROOMS.BATHROOMS.BATHTUBE
CITYS.AREAS.STREETS.HOUSES.ROOMS.BATHROOMS.BATHTUBE.SHAMPOO
CITYS.AREAS.STREETS.HOUSES.ROOMS.BATHROOMS.BATHTUBE.CONTITIONER
CITYS.AREAS.STREETS.HOUSES.GARDEN
CITYS.AREAS.STREETS.HOUSES.GARDEN.POOL
CITYS.AREAS.STREETS.HOUSES.GARDEN.POOL.WATER
CITYS.AREAS.STREETS.HOUSES.GARDEN.TREE
CITYS.AREAS.STREETS.CARS
CITYS.AREAS.STREETS.CARS.BRAND
CITYS.AREAS.STREETS.CARS.BRAND.LOGO
CITYS.AREAS.STREETS.CARS.COLOR
CITYS.AREAS.STREETS.CARS.TYPE
</pre>
<pre></pre>
&#13;
答案 1 :(得分:0)
您可以使用以下代码。这个&#34;算法&#34;通过完全加点的名称临时存储属性,作为相应嵌套对象的同义词。这样它可以快速检索注入下一行对象的位置。
请注意,如果输入已排序,则算法执行速度最快。如有必要,您可以使用lines.sort()
。
function addNestedObject(obj, lines) {
var map = { '': obj }; // Set starting point for empty path
function addLine(line) {
var name = line.split(".").pop();
var path = line.substr(0, line.length-name.length-1);
if (!map[path]) addLine(path); // recurse to create parent
if (!map[line]) map[line] = map[path][name] = {}; // set name & line synonym
}
// Process each line with above private function.
for (var line of lines.slice().sort()) addLine(line);
return obj; // Might be useful to have as return value as well
};
// Sample input
var lines = [
'CITYS.AREAS',
'CITYS.AREAS.STREETS',
'CITYS.AREAS.STREETS.HOUSES.ROOMS.LIVINGROOMS.TV',
'CITYS.AREAS.STREETS.HOUSES.ROOMS.LIVINGROOMS.TABLE',
'CITYS.AREAS.STREETS.HOUSES.ROOMS.LIVINGROOMS.TABLE.VASE',
'CITYS.AREAS.STREETS.HOUSES.ROOMS.LIVINGROOMS.TABLE.ASTREY',
'CITYS.AREAS.STREETS.HOUSES.ROOMS.BATHROOMS',
'CITYS.AREAS.STREETS.HOUSES.ROOMS.BATHROOMS.BATHTUBE',
'CITYS.AREAS.STREETS.HOUSES.ROOMS.BATHROOMS.BATHTUBE.SHAMPOO',
'CITYS.AREAS.STREETS.HOUSES.ROOMS.BATHROOMS.BATHTUBE.CONTITIONER',
'CITYS.AREAS.STREETS.HOUSES.GARDEN',
'CITYS.AREAS.STREETS.HOUSES.GARDEN.POOL',
'CITYS.AREAS.STREETS.HOUSES.GARDEN.POOL.WATER',
'CITYS',
];
var stractureobj = { 'otherProperty': 42 };
// Convert lines to nested object and add to stractureobj
addNestedObject(stractureobj, lines);
// Output in snippet
document.querySelector('pre').textContent=JSON.stringify(stractureobj, null, 4);
&#13;
<pre></pre>
&#13;
上面使用了一个对象stractureobj
,它已经有了自己的属性,必须在其中添加嵌套结构。
如果你只想拥有一个只有嵌套结构的对象,那么你可以用空对象调用它并分配返回值:
var stractureobj = addNestedObject({}, lines);
与此相同:
var stractureobj = {};
addNestedObject(stractureobj, lines);
答案 2 :(得分:0)
我想在JS中,必须对嵌套值进行“动态”访问以获取或设置它们。我认为这是一个缺少的功能。所以我决定开发两种可重用的Object方法。它们是Object.prototype.getNestedValue()
和Object.prototype.setNestedValue()
它们是用于这些用例的非常方便的工具,只是将您的工作变成一项非常简单的任务。好吧,让我们进入他们看看他们是什么。
setNestedValue()
需要一些参数。除了最后一个参数之外的所有参数都用作对象属性,如果它是"string"
类型或数组索引(如果它是"number"
类型)。最后一个参数是最后一个对象属性或数组索引的值。因此。
var o = {};
o.setNestedValue("a",3,"b","value");
或
var o = {};
o.setNestedValue(...["a",3,"b"],"value");
是典型的用例。让我们看一个简单的例子。
Object.prototype.setNestedValue = function(...a) {
a.length > 2 ? typeof this[a[0]] === "object" && this[a[0]] !== null ? this[a[0]].setNestedValue(...a.slice(1))
: (this[a[0]] = typeof a[1] === "string" ? {} : new Array(a[1]),
this[a[0]].setNestedValue(...a.slice(1)))
: this[a[0]] = a[1];
return this;
};
var o = {};
o.setNestedValue("a",3,"x","value");
o.setNestedValue("a",2,"y","value");
o.setNestedValue("a",1,"z","value");
o.setNestedValue("a",0,"w","value");
console.log(JSON.stringify(o,null,2));
好了,现在是您的解决方案的时间;
Object.prototype.getNestedValue = function(...a) {
return a.length > 1 ? (this[a[0]] !== void 0 && this[a[0]].getNestedValue(...a.slice(1))) : this[a[0]];
};
Object.prototype.setNestedValue = function(...a) {
a.length > 2 ? typeof this[a[0]] === "object" && this[a[0]] !== null ? this[a[0]].setNestedValue(...a.slice(1))
: (this[a[0]] = typeof a[1] === "string" ? {} : new Array(a[1]),
this[a[0]].setNestedValue(...a.slice(1)))
: this[a[0]] = a[1];
return this;
};
var data = "CITYS\nCITYS.AREAS\nCITYS.AREAS.STREETS\nCITYS.AREAS.STREETS.HOUSES\nCITYS.AREAS.STREETS.HOUSES.ROOMS\nCITYS.AREAS.STREETS.HOUSES.ROOMS.KITCHEN\nCITYS.AREAS.STREETS.HOUSES.ROOMS.LIVINGROOMS\nCITYS.AREAS.STREETS.HOUSES.ROOMS.LIVINGROOMS.TV\nCITYS.AREAS.STREETS.HOUSES.ROOMS.LIVINGROOMS.TABLE\nCITYS.AREAS.STREETS.HOUSES.ROOMS.LIVINGROOMS.TABLE.VASE\nCITYS.AREAS.STREETS.HOUSES.ROOMS.LIVINGROOMS.TABLE.ASTREY\nCITYS.AREAS.STREETS.HOUSES.ROOMS.BATHROOMS\nCITYS.AREAS.STREETS.HOUSES.ROOMS.BATHROOMS.BATHTUBE\nCITYS.AREAS.STREETS.HOUSES.ROOMS.BATHROOMS.BATHTUBE.SHAMPOO\nCITYS.AREAS.STREETS.HOUSES.ROOMS.BATHROOMS.BATHTUBE.CONTITIONER\nCITYS.AREAS.STREETS.HOUSES.GARDEN\nCITYS.AREAS.STREETS.HOUSES.GARDEN.POOL\nCITYS.AREAS.STREETS.HOUSES.GARDEN.POOL.WATER\nCITYS.AREAS.STREETS.HOUSES.GARDEN.TREE\nCITYS.AREAS.STREETS.CARS\nCITYS.AREAS.STREETS.CARS.BRAND\nCITYS.AREAS.STREETS.CARS.BRAND.LOGO\nCITYS.AREAS.STREETS.CARS.COLOR\nCITYS.AREAS.STREETS.CARS.TYPE",
datarr = data.split("\n").map(e => e.split(".")), // get your list in an array
o = {};
datarr.forEach(a => o.setNestedValue(...a,""));
console.log(JSON.stringify(o,null,2));
好吧..就是这样......这很简单。