【问题标题】:Javascript: How to create an object from a dot separated string?Javascript:如何从点分隔的字符串创建对象?
【发布时间】:2019-03-18 17:16:27
【问题描述】:

我遇到了这个潜在的场景,我向我的一些员工提出了一个测试问题。我可以想出几种方法来解决这个问题,但它们都不是很漂亮。我想知道什么解决方案可能最适合这个以及任何优化技巧。问题来了:

给定一些任意长度的点符号字符串“mystr”(例如,mystr = “node1.node2.node3.node4”),编写一个名为“expand”的函数,将这些项目中的每一个创建为一个新的节点层在一个 js 对象中。对于上面的示例,假设我的对象名称是“blah”,它应该输出以下内容:

blah: { node1: { node2: { node3: { node4: {}}}}}

来自函数调用:

mystr = "node1.node2.node3.node4";
blah = {};
expand(blah,mystr);

或者,如果更简单,可以创建函数以将变量设置为返回值:

mystr = "node1.node2.node3.node4";
blah = expand(mystr);

额外的功劳:有一个可选的函数参数,它将设置最后一个节点的值。因此,如果我将我的函数称为“expand”并像这样调用它:expand(blah, mystr, "value"),则输出应该与以前相同,但使用 node4 = "value" 而不是 {}。

【问题讨论】:

  • 您应该将您的解决方案发布到CodeReview 并在那里寻求改进。
  • 这本质上是一个 DFS(深度优先搜索),它使用堆栈来跟踪您所在的级别。
  • @dave:这主要是假设的代码,与代码审查无关。

标签: javascript object


【解决方案1】:

ES6 你可以这样做:

function expand(str, val = {}) {
  return str.split('.').reduceRight((acc, currentValue) => {
    return { [currentValue]: acc }
  }, val)
}

const blah = expand('a.b.c.d', 'last value')

【讨论】:

    【解决方案2】:

    这是我脑海中突然出现的一种方法。它以点表示法拆分字符串,然后循环遍历节点以在对象内部创建对象,使用“移动引用”(但不确定这是否是正确的术语)。

    函数中的对象output 包含整个函数中正在构建的完整对象,但ref 保留了一个在output 中越来越深的引用,因为新的子对象在for-中创建循环。

    最后,最后一个值被应用到最后一个给定的名字。

    function expand(str, value)
    {
        var items = mystr.split(".") // split on dot notation
        var output = {} // prepare an empty object, to fill later
        var ref = output // keep a reference of the new object
    
        //  loop through all nodes, except the last one
        for(var i = 0; i < items.length - 1; i ++)
        {
            ref[items[i]] = {} // create a new element inside the reference
            ref = ref[items[i]] // shift the reference to the newly created object
        }
    
        ref[items[items.length - 1]] = value // apply the final value
    
        return output // return the full object
    }
    

    然后返回对象,所以可以使用这个表示法:

    mystr = "node1.node2.node3.node4";
    blah = expand(mystr, "lastvalue");
    

    【讨论】:

    • @Oscar 为什么没有分号?
    • 它们不是强制性的,但拥有它们被认为是一种好习惯。没有它们,这里的函数就无法缩小,但是 cmets 也需要去。
    • 在我看来,没有分号它看起来更干净。如果您知道何时应该使用它们,则可以在安全的情况下将它们排除在外。 UglifyJS2 在没有分号的情况下完美地缩小了这一点。这一直是一个有争议的话题,但 JavaScript 的分号大多数时候是可选的。
    • Douglas Crockford 将在此回复中not be happy
    • 好吧,就像我说的那样,这是一个非常有争议的话题,因此您所链接的主题的 cmets 中的意见非常不同。
    【解决方案3】:
    var obj = {a:{b:{c:"a"}}};
    const path = "a.b.c".split(".");
    while(path.length > 1){
       obj = obj[path.shift()];
    }
    obj[path.shift()] = "a";
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-01-30
      • 2020-12-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多