Javascript 2d到3d对象

时间:2016-01-29 16:11:14

标签: 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",
    "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”键,则可以。阵列中可能有数万个对象,因此速度很重要。我无法找到一种方法来有效地执行此操作,因为需要跟踪父节点以了解子项的放置位置。 “Level”键保证大于或等于0.“Level”键也保证最多比数组中前一个元素的“Level”键高1。换句话说,0 <= array[i].Level <= array[i+1].Level - 1。感谢。

3 个答案:

答案 0 :(得分: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>

答案 1 :(得分:0)

菲利克斯·克林提出了这个主意。

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;
}

答案 2 :(得分:0)

基本上,我们需要做的就是获取当前级别并将其自身添加到其父级。节点的结构是递归的:

error: no matching function for call to 'BankAccount::BankAccount()'

我们可以使用map,其中key = Level和value = node来跟踪最新的父级。为了得到父母,我们简单地使用

{"Text": "some text", "nodes": []}

我们可以使用虚拟节点作为父节点启动并使其级别为-1。 代码如下:

map[level - 1]

由于这是一次通过,时间复杂度为O(n)。