點燈坊

失くすものさえない今が強くなるチャンスよ

Finding Value with Recursive Object

Sam Xiao's Avatar 2022-11-20

Sometimes we may get data by the data structure of a Recursive Object. We have to write some recursive functions to find value with these Recursive Objects.

Version

ECMAScript 2015

ID Property

let data = {
  id: 1,
  name: 'Sam',
  parent: {
    id: 2,
    name: 'John',
    parent: {
      id: 3,
      name: 'Tom',
    },
  },
}

let f = (o, x) => {
  if (o.id === x) return o.name
  else if (o.parent) return f(o.parent, x)
  else return undefined
}

f(data, 1) // ?
f(data, 2) // ?
f(data, 3) // ?
f(data, 4) // ?

Line 1

let data = {
  id: 1,
  name: 'Sam',
  parent: {
    id: 2,
    name: 'John',
    parent: {
      id: 3,
      name: 'Tom'
    }
  },
}
  • data is a nested Object
  • If we can’t find value with id, we have to use the parent property for nested Object to find another id

Line 14

let f = (o, x) => {
  if (o.id === x) return o.name
  else if (o.parent) return f(o.parent, x)
  else return undefined
}
  • Pass Object and id to find the corresponding value
  • If id property equals id, just return the name property
  • If id is not found and parent property exists, pass the nested Object to find id
  • If id is not found and the parent property doesn’t exist, it is the last Object of the nested Object. Just return undefined

recursive000

let data = [
  {
    id: 1,
    name: 'Sam',
    parent: {
      id: 4,
      name: 'Ken',
      parent: {
        id: 7,
        name: 'Dan',
      },
    },
  },
  {
    id: 2,
    name: 'John',
    parent: {
      id: 5,
      name: 'Ray',
      parent: {
        id: 8,
        name: 'Fan',
      },
    },
  },
  {
    id: 3,
    name: 'Tom',
    parent: {
      id: 6,
      name: 'Ben',
      parent: {
        id: 9,
        name: 'Mon',
      },
    },
  },
]

let f = (o, x) => {
  if (o.id === x) return o.name
  else if (o.parent) return f(o.parent, x)
  else return undefined
}

let g = (a, x) => {
  for (o of a) {
    let result = f(o, x)

    if (result) return result
    else continue
  }
}

g(data, 1) // ?
g(data, 2) // ?
g(data, 3) // ?
g(data, 4) // ?
g(data, 5) // ?
g(data, 6) // ?
g(data, 7) // ?
g(data, 8) // ?
g(data, 9) // ?
g(data, 10) // ?

Line 1

let data = [
  {
    id: 1,
    name: 'Sam',
    parent: {
      id: 4,
      name: 'Ken',
      parent: {
        id: 7,
        name: 'Dan',
      },
    },
  },
  {
    id: 2,
    name: 'John',
    parent: {
      id: 5,
      name: 'Ray',
      parent: {
        id: 8,
        name: 'Fan',
      },
    },
  },
  {
    id: 3,
    name: 'Tom',
    parent: {
      id: 6,
      name: 'Ben',
      parent: {
        id: 9,
        name: 'Mon',
      },
    },
  },
]
  • data is an Array. It collects many nested Objects

Line 40

let f = (o, x) => {
  if (o.id === x) return o.name
  else if (o.parent) return f(o.parent, x)
  else return undefined
}
  • f() is a function to find id from a nested Object

Line 46

let g = (a, x) => {
  for (o of a) {
    let result = f(o, x)

    if (result) return result
    else continue
  }
}
  • g() is a function to find id from an Array of nested Objects
  • for of loop through the Array and every item is an Object
  • Use f() to search all nested Objects of the Object
  • If f() finds id, then returns the value, else continue to next of Object of the Array

recursive001

Key as ID

let data = {
  1: { 
    name: 'Sam',
    parent: {
      2: {
        name: 'Ken',
        parent: {
          3: {
            name: 'Dan'
          }
        }
      }
    }
  }
}

let f = (o, x) => {
  if (o[x]) return o[x].name
  else if (Object.values(o)[0].parent) return f(Object.values(o)[0].parent, x)
  else return undefined
}

f(data, 1) // ?
f(data, 2) // ?
f(data, 3) // ?
f(data, 4) // ?

Line 1

let data = {
  1: { 
    name: 'Sam',
    parent: {
      2: {
        name: 'Ken',
        parent: {
          3: {
            name: 'Dan'
          }
        }
      }
    }
  }
}
  • Another Recursive Object is Key as ID. No id property anymore
  • If we can’t find value with the key, we have to use the parent property for the nested Object to find another key

Line 17

let f = (o, x) => {
  if (o[x]) return o[x].name
  else if (Object.values(o)[0].parent) return f(Object.values(o)[0].parent, x)
  else return undefined
}
  • Pass Object and id to find the corresponding value
  • If an Object with id as key exists, just return the name property
  • If an Object with id as key doesn’t exist but its parent property exists, pass the nested Object to find id
  • If an Object with id as key doesn’t exist and so does its parent property, it is the last Object of the nested Object. Just return undefined

recursive002

let data = {
  1: { 
    name: 'Sam',
    parent: {
      4: {
        name: 'Ken',
        parent: {
          7: {
            name: 'Dan'
          }
        }
      }
    }
  },
  2: {
    name: 'John', 
    parent: {
      5: {
        name: 'Ray',
        parent: {
          8: {
            name: 'Fan'
          }
        }
      }
    }
  },
  3: { 
    name: 'Tom',
    parent: {
      6: {
        name: 'Ben',
        parent: {
          9: {
            name: 'Mon'
          }
        }
      }
    } 
  }
}

let f = (o, x) => {
  if (o[x]) return o[x].name
  else if (Object.values(o)[0].parent) return f(Object.values(o)[0].parent, x)
  else return undefined
}

let g = (o, x) => {
  for(let t in o) {
    if (Number(t) === x) return o[t].name
    else {
      let result = f(o[t].parent, x)
      if (result) return result
      else continue
    }
  }
}

g(data, 1) // ?
g(data, 2) // ?
g(data, 3) // ?
g(data, 4) // ?
g(data, 5) // ?
g(data, 6) // ?
g(data, 7) // ?
g(data, 8) // ?
g(data, 9) // ?
g(data, 10) // ?

Line 1

let data = {
  1: { 
    name: 'Sam',
    parent: {
      4: {
        name: 'Ken',
        parent: {
          7: {
            name: 'Dan'
          }
        }
      }
    }
  },
  2: {
    name: 'John', 
    parent: {
      5: {
        name: 'Ray',
        parent: {
          8: {
            name: 'Fan'
          }
        }
      }
    }
  },
  3: { 
    name: 'Tom',
    parent: {
      6: {
        name: 'Ben',
        parent: {
          9: {
            name: 'Mon'
          }
        }
      }
    } 
  }
}
  • data is an Object. It collects many nested Objects with key as Key as ID

Line 43

let f = (o, x) => {
  if (o[x]) return o[x].name
  else if (Object.values(o)[0].parent) return f(Object.values(o)[0].parent, x)
  else return undefined
}
  • f() is a function to find id from a nested Object

Line 49

let g = (o, x) => {
  for(let t in o) {
    if (Number(t) === x) return o[t].name
    else {
      let result = f(o[t].parent, x)
      if (result) return result
      else continue
    }
  }
}
  • g() is a function to find id from an Object of nested Objects
  • for in loop through the Object and every item is key and its type is String
  • If the key equals id, just return its name property
  • If the key is not equal to id, use f() to search all nested Objects of the Object
  • If id exists in any nested Object, just return its name property
  • If id doesn’t exist in any nested Object, continue to the next key of the Object

recursive003

Conclusion

  • We seldom write recursive functions on JavaScript. But the only way to find value for Recursive Object data structure is to write Recursive Function