创建包含N'的嵌套对象嵌套对象来自.txt文件Javascript

时间:2016-05-21 21:44:20

标签: javascript object multidimensional-array

经过多次尝试和搜索,我决定问,因为我卡住了。我有一个这样的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中找到的东西组合但它不起作用。

3 个答案:

答案 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)
  }
};

&#13;
&#13;
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;
&#13;
&#13;

答案 1 :(得分:0)

您可以使用以下代码。这个&#34;算法&#34;通过完全加点的名称临时存储属性,作为相应嵌套对象的同义词。这样它可以快速检索注入下一行对象的位置。

请注意,如果输入已排序,则算法执行速度最快。如有必要,您可以使用lines.sort()

&#13;
&#13;
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;
&#13;
&#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));

好吧..就是这样......这很简单。