如何递归地对象化一个字符串

How to recursively objectify a string

在尝试更熟悉递归函数的同时,我尝试编写一个函数,它接受一个点分隔的字符串并将其转换为一个对象。 因此,给定以下字符串:user.first.name.robert 此函数应该 return 以下对象:

{
  user: {
    first: {
      name: 'robert'
    }
  }
}

这是我的尝试:

function objectifyHelper(array, object) {
    if (array.length === 2) {
        const [key, value] = array;
        object[key] = value;
        return object;
    } else {
        object[array[0]] = objectifyHelper(array.slice(1), object); 
        return object;
    }
}

function objectify(string) {
    const tokens = string.split('.');
    return objectifyHelper(tokens, {});
}

const str = 'user.first.name.robert';
const result = objectify(str);

这让我得到以下结果:

result <ref *1> {
  name: 'robert',
  first: [Circular * 1],
  user: [Circular * 1]
}

我做错了什么?

您在这里只创建了一个对象:

return objectifyHelper(tokens, {});

每次分配 属性 时都会使用它。您需要在递归时创建一个新对象,而不仅仅是在 objectify.

内部

更简单的方法是:

const objectify = string => string
  .split('.')
  .reduceRight(
    (innerObj, prop) => ({ [prop]: innerObj })
  );

const str = 'user.first.name.robert';
const result = objectify(str);
console.log(result);

你快到了。但是,如果您的助手接受了一个对象,但也 return 发送了它,请在递归调用中保持一致

function objectifyHelper(array, object) {
    if (array.length === 2) {
        const [key, value] = array;
        object[key] = value;
        return object;
    } else {
        object[array[0]] = objectifyHelper(array.slice(1), {}); 
        return object;
    }
}

function objectify(string) {
    const tokens = string.split('.');
    return objectifyHelper(tokens, {});
}

const str = 'user.first.name.robert';
const result = objectify(str);

console.log(result)

请注意,这只会改变您的

object[array[0]] = objectifyHelper(array.slice(1), object); 

object[array[0]] = objectifyHelper(array.slice(1), {}); 

阅读问题下OP的评论,我认为进一步扩大答案是公平的。

是的,将新创建的对象传递给递归函数然后 returning 它可以简化。一种可能的方法是消除将对象传递给函数的需要,而只是 return 一个新创建的对象给调用者。

因此,简化版本是

function objectifyHelper(array) {
    // we always create a new object
    var object = {};
    if (array.length === 2) {
        const [key, value] = array;
        object[key] = value;
    } else {    
        object[array[0]] = objectifyHelper(array.slice(1)); 
    }
    // and return it
    return object;
}

function objectify(string) {
    const tokens = string.split('.');
    return objectifyHelper(tokens);
}

const str = 'user.first.name.robert';
const result = objectify(str);

console.log(result);