Search code examples
javascriptlodashnest-nested-object

Lodash ._sample with nested objects


I have an object with nested objects like this:

var SimpleWeapons = {

    properties: "SimpleWeapons",

  Club:{Name:"Club", Cost:"1sp", Damage:"1d4 bludgeoning", Weight:"2lb", Properties:"Light"},
  Dagger:{Name:"Dagger" , Cost:"    2 gp" , Damage: "1d4 piercing", Weight:"1lb" , Properties:"Finesse, light, thrown (range 20/60)"},
  Greatclub:{Name:"Greatclub" , Cost:"2sp" , Damage: "1d8 bludgeoning   ", Weight:"10 lb" , Properties:"Two-handed"},
  Handaxe:{Name:"Handaxe" , Cost:"5gp" , Damage: "1d6 slashing", Weight:"2lb" , Properties:"Light, thrown (range 20/60)"},
  Javelin:{Name:"Javelin" , Cost:"5sp" , Damage: "1d6 piercing", Weight:"2lb" , Properties:"Thrown (range 30/120)"},
  LightHammer:{Name:"Light Hammer" , Cost:"2gp" , Damage: "1d4 bludgeoning", Weight:"2lb" , Properties:"Light, thrown (range 20/60)"},
  Mace:{Name:"Mace" , Cost:"5gp" , Damage: "1d6 bludgeoning", Weight:"4lb" , Properties:""},
  Quarterstaff:{Name:"Quarterstaff" , Cost:"2sp" , Damage: "1d6 bludgeoning", Weight:"4lb" , Properties:"Versatile (1d8)"},
  Sickle:{Name:"Sickle" , Cost:"1gp" , Damage: "1d4 slashing", Weight:"2lb" , Properties:"Light"},
  Spear:{Name:"Spear" , Cost:"1gp" , Damage: "1d6 piercing", Weight:"3lb" , Properties:"Thrown (range 20/60), versatile (1d8)"}

}

I would like to return one of the nested object properties (as as string) at random, so "Club" or "Dagger" using a function. I have used _.sample and _.sampleSize in flatter objects in this project in the following manner:

var getDefaultEquipment = (chaClass) => {
    if(chaClass === "Bard"){
        var equipment = {};
        equipment.equipment = (_.sampleSize(classes.Bard.equipment,1));
        return equipment;}}

but I'm unsure how to dig a little deeper, or even if it's possible?


Solution

  • If you only want one result, use _.sample to get one random item. I would also use _.omit to make sure that you don't pull the properties key, which isn't a valid weapon.

    Once you have a random object from the _.sample call, you can get its name in the usual way by using dot notation: .Name.

    Example:

    var SimpleWeapons = {
    
      properties: "SimpleWeapons",
    
      Club: {
        Name: "Club",
        Cost: "1sp",
        Damage: "1d4 bludgeoning",
        Weight: "2lb",
        Properties: "Light"
      },
      Dagger: {
        Name: "Dagger",
        Cost: "    2 gp",
        Damage: "1d4 piercing",
        Weight: "1lb",
        Properties: "Finesse, light, thrown (range 20/60)"
      },
      Greatclub: {
        Name: "Greatclub",
        Cost: "2sp",
        Damage: "1d8 bludgeoning   ",
        Weight: "10 lb",
        Properties: "Two-handed"
      },
      Handaxe: {
        Name: "Handaxe",
        Cost: "5gp",
        Damage: "1d6 slashing",
        Weight: "2lb",
        Properties: "Light, thrown (range 20/60)"
      },
      Javelin: {
        Name: "Javelin",
        Cost: "5sp",
        Damage: "1d6 piercing",
        Weight: "2lb",
        Properties: "Thrown (range 30/120)"
      },
      LightHammer: {
        Name: "Light Hammer",
        Cost: "2gp",
        Damage: "1d4 bludgeoning",
        Weight: "2lb",
        Properties: "Light, thrown (range 20/60)"
      },
      Mace: {
        Name: "Mace",
        Cost: "5gp",
        Damage: "1d6 bludgeoning",
        Weight: "4lb",
        Properties: ""
      },
      Quarterstaff: {
        Name: "Quarterstaff",
        Cost: "2sp",
        Damage: "1d6 bludgeoning",
        Weight: "4lb",
        Properties: "Versatile (1d8)"
      },
      Sickle: {
        Name: "Sickle",
        Cost: "1gp",
        Damage: "1d4 slashing",
        Weight: "2lb",
        Properties: "Light"
      },
      Spear: {
        Name: "Spear",
        Cost: "1gp",
        Damage: "1d6 piercing",
        Weight: "3lb",
        Properties: "Thrown (range 20/60), versatile (1d8)"
      }
    }
    
    const randomWeapon = _.sample(_.omit(SimpleWeapons, "properties")).Name;
    console.log("A random weapon:", randomWeapon);
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>