当属性为null时如何使用if语句

时间:2018-06-07 19:20:10

标签: javascript algorithm if-statement recursion binary-tree

我有一个简单的if语句如图所示。但是,递归语句最终没有val值而不是执行我的其余代码窗口PowerShell只存在TypeError:无法读取属性' val' null。

chkL = (L) => {
    if(L.left.val) chkL(L.left);
}

以下是完整代码:

function TreeNode(val) {
    this.val = val;
    this.left = this.right = null;
}

let tree1 = new TreeNode(1);
tree1.left = new TreeNode(3);
tree1.right = new TreeNode(2);
tree1.left.left = new TreeNode(5);

let tree2 = new TreeNode(2);
tree2.left = new TreeNode(1);
tree2.right = new TreeNode(3);
tree2.left.right = new TreeNode(4);
tree2.right.right = new TreeNode(7);

var mergeTrees = function(t1, t2) {
    let ans = Object.assign({}, t1);

    chkL = (L) => {
        if(L.left.val) chkL(L.left);
    }

    if(t1.left.val) {
        chkL(t1.left);
    }


};

mergeTrees(tree1, tree2);

我想知道是否有一种方法可以使用eval()或尝试使用if语句来阻止脚本中断?注意,我知道我可以简单地删除逻辑的.val部分,但我只是对如何执行与此类似的代码感到好奇。

4 个答案:

答案 0 :(得分:2)

我认为你应该使用这样的东西:

if (t1.left && t1.left.val) {
  // do stuff
}

如果对象左侧不存在属性val,则此if语句仅计算为false,并且不会中断。

答案 1 :(得分:0)

使用ES6解构:

const chkL = ({ left, left: { val } = {} }) => {
    if (val) {
        chkL(left);
    }
    // the invisible last line in all JS functions
    return undefined;
}

现在这个函数编写起来可以简单得多:

const chkL = () => undefined;

答案 2 :(得分:0)

你可以试试这个:

L.left ? chkL(L.left) : "else condition"

如果需要,可以添加其他条件

答案 3 :(得分:0)

递归功能正常

递归是一种功能性遗产,因此以函数式编写程序将产生最佳结果。这意味着避免突变,空检查和其他副作用。而不是屠宰你的代码,我只是希望一个不同的程序能够清楚地表明有更好的方法来解决这个问题......

我们从EmptyNode

开始
const Empty =
  {}

const Node = (value, left = Empty, right = Empty) =>
  ({ value, left, right })

通往merge两个节点的方法

const merge = (n1, n2) =>
  n1 === Empty
    ? n2

  : n2 === Empty
    ? n1

  : Node ( n1.value + n2.value // some merging operation!
         , merge (n1.left, n2.left)
         , merge (n1.right, n2.right)
         )

现在我们采用两棵树,t1t2

const t1 =
  Node ('A'
       , Node ('B')
       , Node ('C', Node ('D'), Node ('E'))
       )

const t2 =
  Node ('a'
       , Node ('b', Node ('x'))
       , Node ('c'
              , Node ('d', Node ('y'))
              )
       )

为了了解发生了什么,我们向print

添加了一些功能
const print = (node, pre = '', child = '') =>
  node === Empty
    ? ""
    : print (node.left, child + '┌── ', child + '.   ')
      + pre + String (node.value) + '\n'
      + print (node.right, child + '└── ', child + '.   ')

console.log (print (t1)
// ┌── B
// A
// .   ┌── D
// └── C
// .   └── E

console.log (print (t2))
// .   ┌── x
// ┌── b
// a
// .   .   ┌── y
// .   ┌── d
// └── c

现在举行庆祝活动 - 请注意,t1t2都不会因调用merge而更改。形成了一个全新的t3

const t3 =
  merge (t1, t2)

console.log (print (t3))
// .   ┌── x
// ┌── Bb
// Aa
// .   .   ┌── y
// .   ┌── Dd
// └── Cc
// .   └── E

在浏览器中运行完整程序

const Empty =
  {}

const Node = (value, left = Empty, right = Empty) =>
  ({ value, left, right })
  
const merge = (n1, n2) =>
  n1 === Empty
    ? n2
  
  : n2 === Empty
    ? n1
    
  : Node ( n1.value + n2.value // some merging function!
         , merge (n1.left, n2.left)
         , merge (n1.right, n2.right)
         )

const print = (node, pre = '', child = '') =>
  node === Empty
    ? ""
    : print (node.left, child + '┌── ', child + '.   ')
      + pre + String (node.value) + '\n'
      + print (node.right, child + '└── ', child + '.   ')

const t1 =
  Node ('A'
       , Node ('B')
       , Node ('C', Node ('D'), Node ('E'))
       )
       
const t2 =
  Node ('a'
       , Node ('b', Node ('x'))
       , Node ('c'
              , Node ('d', Node ('y'))
              )
       )
       
console.log (print (t1))
// ┌── B
// A
// .   ┌── D
// └── C
// .   └── E

console.log (print (t2))
// .   ┌── x
// ┌── b
// a
// .   .   ┌── y
// .   ┌── d
// └── c

const t3 =
  merge (t1, t2)

console.log (print (t3))
// .   ┌── x
// ┌── Bb
// Aa
// .   .   ┌── y
// .   ┌── Dd
// └── Cc
// .   └── E

功能意味着灵活

对此计划的明显改进将涉及使merge成为更高阶函数,以使+不会硬编码到我们的程序中

// improved merge; user-defined merging function, f
const merge = (f, n1, n2) =>
  n1 === Empty
    ? n2

  : n2 === Empty
    ? n1

  : Node ( f (n1.value, n2.value) // <---
         , merge (f, n1.left, n2.left)
         , merge (f, n1.right, n2.right)
         )

现在merge的调用者可以定义值的组合方式。在此示例中,我们将两个值都放入数组

const t4 =
  merge ((v1,v2) => [v1, v2], t1, t2)

console.log (print (t4))
// .   ┌── x
// ┌── B,b
// A,a
// .   .   ┌── y
// .   ┌── D,d
// └── C,c
// .   └── E

现在,当我们print树时,数组将转换为字符串。这里的另一个明显改进是调整print函数,类似于我们对merge所做的操作,允许用户指定 值的打印方式

// improved print; String is no longer hard-coded
const print = (node, fmt = String, pre = '', child = '') =>
  node === Empty
    ? ""
    : print (node.left, fmt, child + '┌── ', child + '.   ')
      + pre + fmt (node.value) + '\n' // <---
      + print (node.right, fmt, child + '└── ', child + '.   ')

现在我们可以将格式化函数指定为第二个参数

console.log (print (t4, JSON.stringify)) // print as JSON!
// .   ┌── "x"
// ┌── ["B","b"]
// ["A","a"]
// .   .   ┌── "y"
// .   ┌── ["D","d"]
// └── ["C","c"]
// .   └── "E"

在上面的树中,我们为""个节点输出Empty。也许我们想要一种可视化它们的方法,因此我们可以再次修改print函数

// improved print; displays Empty nodes as ∅
const print = (node, fmt = String, pre = '', child = '') =>
  node === Empty
    ? pre + '\u2205\n' // <---
    : print (node.left, fmt, child + '┌── ', child + '.   ')
      + pre + fmt (node.value) + '\n'
      + print (node.right, fmt, child + '└── ', child + '.   ')

console.log (print (t3))
// .   .   ┌── ∅
// .   ┌── x
// .   .   └── ∅
// ┌── Bb
// .   └── ∅
// Aa
// .   .   .   ┌── ∅
// .   .   ┌── y
// .   .   .   └── ∅
// .   ┌── Dd
// .   .   └── ∅
// └── Cc
// .   .   ┌── ∅
// .   └── E
// .   .   └── ∅