Javascript数组到对象

时间:2016-02-18 22:17:28

标签: javascript

我有一个看起来像这样的数组:

files = [
  'Dashboard/Logs/Errors',
  'Dashboard/Logs/Other',
  'Accounts/Main',
]

我想让它看起来像这样:

navigation = [
  {
    "title": "Dashboard",
    "dropdown": [
      {
        "title": "Logs",
        "dropdown": [
          {
            "title": "Errors",
          },
          {
            "title": "Other",
          }
        ]
      }
    ]
  },
  {
    "title": "Accounts",
    "dropdown": [
      {
        "title": "Main",
      }
    ]
  }
]

到目前为止,我有以下内容:

var navigation = [];
for (var i = 0; i < files.length; i++) {
  var parts = files[i].split('/');
  navigation.push({title: parts[0]});
  for (var j = 1; j < parts.length; j++) {

  }
}

我很难找到一个体面的方法来做到这一点。到目前为止我已经无法工作,因为它在导航下创建了两个对象,每个对象都有title: "Dashboard"。任何想法聪明的方法?谢谢:))

2 个答案:

答案 0 :(得分:7)

这应该产生所需的输出:

var files = [
  'Dashboard/Logs/Errors',
  'Dashboard/Logs/Other',
  'Accounts/Main',
];

var navigation = [];
// Iterates through a navigation array and returns the object with matching title, if one exists.
var getNavigationObject = function(nav, title) {
  for (var i = 0; i < nav.length; i++) {
    if (nav[i].title == title) {
      return nav[i];
    }
  }
};
// Adds a file to the nav.
// The input is an array of file components (i.e. file.split('/'))
// This works by recursively adding each component of a file.
var addToNav = function (nav, components) {
  var n = getNavigationObject(nav, components[0]);
  if (!n) {
    n = {
      title: components[0]
    };
    nav.push(n);
  }
  if (components.length > 1) {
    n.dropdown = n.dropdown || [];
    addToNav(n.dropdown, components.slice(1));
  }
};

// Actually call `addToNav` on each file.
files.forEach(function(e) {
  addToNav(navigation, e.split('/'));
});

// Produces the result in string form.
JSON.stringify(navigation, null, 2)

这可以通过递归检查给定元素是否已经与文件的组件匹配来实现。如果是,它会重复进入该组件&#34;&#34;下拉&#34;。否则,它会创建它。

答案 1 :(得分:1)

这是一种使用临时对象和一些没有搜索开销的数组方法的方法。

&#13;
&#13;
var files = ['Dashboard/Logs/Errors', 'Dashboard/Logs/Other', 'Accounts/Main'],
    navigation = function (data) {
        var r = [], o = {};
        data.forEach(function (a) {
            var s = r;
            a.split('/').reduce(function (p, b) {
                if (p.children) {
                    p.value.dropdown = p.value.dropdown || [];
                    s = p.value.dropdown;
                    p = p.children;
                }
                if (!(b in p)) {
                    p[b] = { value: { title: b }, children: {} };
                    s.push(p[b].value);
                }
                return p[b];
            }, o);
        });
        return r;
    }(files);

document.write('<pre>' + JSON.stringify(navigation, 0, 4) + '</pre>');
&#13;
&#13;
&#13;