Javascript二维到三维对象

Javascript二维到三维对象,javascript,arrays,object,Javascript,Arrays,Object,我有一个如下格式的数组: [ { "Level": "0", "Text": "My text 1", }, { "Level": "1", "Text": "My text 2", }, { "Level": "1", "Text": "My text 3", }, { "Level": "2", "Text": "My text 4", }, { "Level": "3", "

我有一个如下格式的数组:

[
  {
    "Level": "0",
    "Text": "My text 1",
  },
  {
    "Level": "1",
    "Text": "My text 2",
  },
  {
    "Level": "1",
    "Text": "My text 3",
  },
  {
    "Level": "2",
    "Text": "My text 4",
  },
  {
    "Level": "3",
    "Text": "My text 5",
  },
  {
    "Level": "1",
    "Text": "My text 6",
  },
  {
    "Level": "0",
    "Text": "My text 7",
  }
]
[
  {
    "Text": "My text 1",
    "nodes": [
      {
        "Text": "My text 2",
      },
      {
        "Text": "My text 3",
        "nodes": [
          {
            "Text": "My text 4",
            "nodes": [
              {
                "Text": "My text 5",
              }
            ]
          }
        ]
      },
      {
        "Text": "My text 6",
      }
    ]
  },
  {
    "Text": "My text 7",
  }
]
我想将其转换为如下格式:

[
  {
    "Level": "0",
    "Text": "My text 1",
  },
  {
    "Level": "1",
    "Text": "My text 2",
  },
  {
    "Level": "1",
    "Text": "My text 3",
  },
  {
    "Level": "2",
    "Text": "My text 4",
  },
  {
    "Level": "3",
    "Text": "My text 5",
  },
  {
    "Level": "1",
    "Text": "My text 6",
  },
  {
    "Level": "0",
    "Text": "My text 7",
  }
]
[
  {
    "Text": "My text 1",
    "nodes": [
      {
        "Text": "My text 2",
      },
      {
        "Text": "My text 3",
        "nodes": [
          {
            "Text": "My text 4",
            "nodes": [
              {
                "Text": "My text 5",
              }
            ]
          }
        ]
      },
      {
        "Text": "My text 6",
      }
    ]
  },
  {
    "Text": "My text 7",
  }
]

如果没有从每个对象中删除“级别”键,则可以。阵列中可能有成千上万个对象,因此速度很重要。我无法找到一种有效的方法来实现这一点,因为需要跟踪父节点以知道子节点的位置。“级别”键保证大于或等于0。“Level”键也保证最多比数组中前一个元素的“Level”键高1。换句话说,
0我只是添加了未测试的逻辑。它可以帮助你扩展你的逻辑。如果您需要可执行的解决方案,请告诉我

<script type="text\javascript">
var a=
[
  {
    "Level": "0",
    "Text": "My text 1",
  },
  {
    "Level": "1",
    "Text": "My text 2",
  },
  {
    "Level": "1",
    "Text": "My text 3",
  },
  {
    "Level": "2",
    "Text": "My text 4",
  },
  {
    "Level": "3",
    "Text": "My text 5",
  },
  {
    "Level": "1",
    "Text": "My text 6",
  },
  {
    "Level": "0",
    "Text": "My text 7",
  }
];

// first sort by level. I didn't include that code. Let me know if you want.

var newLevels=[];
var prevLevel="";
var newNode=null;


for(var index=0;index<a.length;index++)
{
    if(a[index].Level != prevLevel)
    {
        newNode = {Text : a[index].Text};

        newLevels.push(newNode);
    }
    else
    {
        newNode.nodes=[{Text: a[index].Text}];
    }

     prevLevel = a[index].Level;
}
</script>

变量a=
[
{
“级别”:“0”,
“文本”:“我的文本1”,
},
{
“级别”:“1”,
“文本”:“我的文本2”,
},
{
“级别”:“1”,
“文本”:“我的文本3”,
},
{
“级别”:“2”,
“文本”:“我的文本4”,
},
{
“级别”:“3”,
“文本”:“我的文本5”,
},
{
“级别”:“1”,
“文本”:“我的文本6”,
},
{
“级别”:“0”,
“文本”:“我的文本7”,
}
];
//首先按级别排序。我没有包括那个代码。如果你愿意,请告诉我。
var newLevels=[];
var prevLevel=“”;
var newNode=null;

对于(var index=0;indexFelix Kling给出了这个想法

function makeTable3D(oldTable) {
  var deferred  = q.defer();
  var parents = [];
  var table = [];

  for (var i = 0; i < oldTable.length; i++) {
    var level = parseInt(oldTable[i].Level) + 1;
    if (isNaN(level)) {
      continue;
    }

    if (parents.length < level) {
      parents.push(0);
    } else if (parents.length > level) {
      while (parents.length > level) {
        parents.pop();
      }
      parents.push(parents.pop() + 1);
    } else {
      parents.push(parents.pop() + 1);
    }

    var current = table;
    for (var j = 0; j < parents.length - 1; j++) {
      if (current[parents[j]].nodes) {
        current = current[parents[j]].nodes;
      } else {
        current = current[parents[j]];
        current.nodes = [];
        current = current.nodes;
      }
    }
    oldTable[i].Level = parseInt(oldTable[i].Level);
    current.push(oldTable[i]);
  }

  deferred.resolve(table);
  return deferred.promise;
}
函数makeTable3D(oldTable){
var deferred=q.deferred();
var父项=[];
var表=[];
对于(变量i=0;ilevel){
while(parents.length>level){
parents.pop();
}
parents.push(parents.pop()+1);
}否则{
parents.push(parents.pop()+1);
}
无功电流=表;
对于(var j=0;j
本质上,我们需要做的就是获取当前级别并将其自身添加到其父级。节点的结构是递归的:

{"Text": "some text", "nodes": []}
我们可以使用一个映射,其中key=Level和value=node来跟踪最新的父节点

map[level - 1]
我们可以使用虚拟节点作为父节点开始,并使其级别为-1。 代码如下:

function convert ( input )
{
    var obj = { "Text": "dummy" };

    var map = { "-1": obj };

    input.forEach(
        function ( i )
        {
            var level = parseInt( i.Level );
            var node = { "Text": i.Text };
            map[ level ] = node;
            if ( !("nodes" in map[ level - 1 ]) )
                map[ level - 1 ].nodes = [];
            map[ level - 1 ].nodes.push( node );
        }
    );
    return obj.nodes;
}

由于这是一个过程,时间复杂度为O(n).

我们可以帮助修复您的代码,但我们不会为您编写代码。也许您首先需要这个。我不需要代码。只需要逻辑。我想不出一种可行的方法。我原本计划跟踪上一个节点。如果当前节点的级别更高,请附加到“节点”。如果级别相同,则按。但是如果级别低于1以上,我不知道将其放置在何处……因此此逻辑不起作用。例如,当我到达“我的文本6”时。我不知道该放在哪里,因为我不知道要返回多少个位置。然后不仅要跟踪上一个节点,还要跟踪所有的祖先。保留一堆代表祖先的节点。然后你可以返回任意祖先并推送到它。很好的呼叫,我想这会起作用。我无法在开始时按级别排序,因为order很重要。所有3级的东西都不属于一起。它属于之前的最后一个2级。