递归地向数组中的每个对象添加相同的元素

时间:2013-09-04 00:51:25

标签: javascript

我有这个对象包含对象数组('pages')

var obj = {
    "pages" : [
        {   
            "title": "title one",
            "sub" : [
                { "title" : "title one one"},
                { "title" : "title one two"}
            ]
        },
        { "title" : "title two" },
        { 
            "title" : "title three",
            "sub" : [
                { "title" : "title three one"},
                { "title" : "title three two"},
                { "title" : "title three three"}
            ]
        }
    ]
}

和这样的预期结果(在'pages'中为每个对象添加'slug'元素)

{
    "pages" : [
        {
            "title" : "title one",
            "slug" : "title-one",
            "sub" : [ 
                {
                    "title" : "title one one",
                    "slug" : "title-one-one"
                },
                {
                    "title" : "title one two",
                    "slug" : "title-one-two"
                }
            ]
        },
        {
            "title" : "title two",
            "slug" : "title-two"
        },
        {
            "title" : "title three",
            "slug"  : "title-three",
            "sub" : [
                {
                    "title" : "title three one",
                    "slug" : "title-three-one"
                },
                {
                    "title" : "title three two",
                    "slug" : "title-three-two"
                },
                {
                    "title" : "title three three",
                    "slug" : "title-three-three"
                }
            ]
        }
    ]
}

我想我可以像

那样做
function add_slug(array_of_obj)
{
    for (var item in array_of_obj) {

        //i am not sure about this:
        item.slug = item.title.replace(/ /g, '-');

        if(typeof item.sub !== undefined) {
            add_slug(item.sub);
        }
    }
}

add_slug(obj.pages);

但我得到undefined item.title我一直在修改这个功能,但它还没有用,所以我需要帮助。感谢。

2 个答案:

答案 0 :(得分:2)

item是表示对象当前属性的字符串。您需要做的是使用item从对象获取属性。

array_of_obj[item].slug = array_of_obj[item].title.replace(/ /g, '-');

if(array_of_obj[item].sub !== undefined) {
    add_item(array_of_obj[item].sub);
}

因此错误是由于item字符串没有title属性,因此它是undefined,因此无法调用.replace()


另外,在测试typeof时,您错误地使用了undefined。不使用typeof进行比较最好。

此外,您的递归调用使用的是add_item,而不是add_slug


最后,在JavaScript中使用for循环而不是for-in循环更好。这有几个原因。在你的具体情况下,它可能没有什么区别,但它仍然是一个更好的做法。

所以你的最终功能看起来像这样:

function add_slug(array_of_obj)
{
    for (var i = 0; i < array_of_obj.length; i++) {

        array_of_obj[i].slug = array_of_obj[i].title.replace(/ /g, '-');

        if(array_of_obj[i].sub !== undefined) {
            add_slug(array_of_obj[i].sub);
        }
    }
}

 add_slug(obj.pages);

或使用ES5功能,如下所示:

function add_slug(array_of_obj)
{
    array_of_obj.forEach(function(item) {

        item.slug = item.title.replace(/ /g, '-');

        if(item.sub !== undefined) {
            add_slug(item.sub);
        }
    }); 
}

 add_slug(obj.pages);

或者不同的方法可能如下所示:

function add_slug(item) {

    item.slug = item.title.replace(/ /g, '-');

    if(item.sub !== undefined) {
        item.sub.forEach(add_slug);
    }
}

obj.pages.forEach(add_slug);

或者这个:

obj.pages.forEach(function add_slug(item) {

    item.slug = item.title.replace(/ /g, '-');

    if(item.sub !== undefined) {
        item.sub.forEach(add_slug);
    }
});

答案 1 :(得分:2)

更改为使用for循环而不是for-in - 更安全的数组。

试试这个:

function add_slug(array_of_obj)
{
    for(var pageIdx = 0; pageIdx < array_of_obj.length; ++pageIdx) {
        var curPage = array_of_obj[pageIdx];

        if(curPage.title) {
            curPage.slug = curPage.title.split(' ').join('-');
        }

        if(curPage.sub) {
            add_slug(curPage.sub);
        }
    }
}

结果:

{
  "pages": [
    {
      "title": "title one",
      "sub": [
        {
          "title": "title one one",
          "slug": "title-one-one"
        },
        {
          "title": "title one two",
          "slug": "title-one-two"
        }
      ],
      "slug": "title-one"
    },
    {
      "title": "title two",
      "slug": "title-two"
    },
    {
      "title": "title three",
      "sub": [
        {
          "title": "title three one",
          "slug": "title-three-one"
        },
        {
          "title": "title three two",
          "slug": "title-three-two"
        },
        {
          "title": "title three three",
          "slug": "title-three-three"
        }
      ],
      "slug": "title-three"
    }
  ]
}