javascriptfunctionobject

JavaScript Pass Object Parameters to Reusable Function


I have a function that I use frequently to lookup parameter values in objects...

let paramDesc = objName.find((e) => e.param1.includes(searchVal));
return paramDesc.param2;

that I would like to turn into reusable code. Here's a working example where I hard-code the object and parameters, followed by my crude attempt to make it resusable:

const noteLocations = [
  { note: ["D3", "C##3"], locations: ["s6f10", "s5f5", "s4f0"]} ,
  { note: ["D#3", "Eb3"], locations: ["s6f11", "s5f6", "s4f1"]} ,
  { note: ["E3", "Fb3"], locations: ["s6f12", "s5f7", "s4f2"]} ,
  { note: ["F3", "E#3"], locations: ["s6f13", "s5f8", "s4f3"]} ,
  { note: ["F#3", "Gb3"], locations: ["s6f14", "s5f9", "s4f4"]} ,
  { note: ["G3", "F##3"], locations: ["s6f15", "s5f10", "s4f5", "s3f0"]} ,
];

function getNoteById(location) {
  let foundLocations = noteLocations.find((e) => e.locations.includes(location));
  if (typeof foundLocations !== "undefined") {
    return foundLocations.note[0];
  } else {
    return "Ø";
  }
}
console.log("Note: " + getNoteById('s4f4'));


function reusableLookup(search4, objName, param1, param2) {
  let parameterDesc = objName.find((e) => e.param1.includes(search4));
  if (typeof parameterDesc !== "undefined") {
    return parameterDesc.param2[0];
  } else {
    return "Ø";
  }
}
console.log("Note: " + reusableLookup('s4f4',noteLocations, locations, note));
console.log("Note: " + reusableLookup('s4f4',noteLocations, noteLocations.locations, noteLocations.note));

Obviously, I'm not very clear on the concept, so that's what I'm trying to learn. There are plenty of similar questions on here, but I didn't see one that addressed it in a way that I could relate directly to provide the answer.


Solution

  • You should use dynamic property access instead, like e[param] instead of e.param:

    function reusableLookup(search4, objName, param1, param2) {
        let parameterDesc = objName.find((e) => e[param1].includes(search4));
        if (typeof parameterDesc !== "undefined") {
            return parameterDesc[param2][0];
        } else {
            return "Ø";
        }
    }
    

    Usage:

    Obviously the variable name locations is not defined here, you should pass the parameters as strings like 'locations'.

    console.log("Note: " + reusableLookup('s4f4',noteLocations, 'locations', 'note'));
    

    Output:

    Note: F#3
    

    The full code snippet:

    const noteLocations = [
        { note: ["D3", "C##3"], locations: ["s6f10", "s5f5", "s4f0"]} ,
        { note: ["D#3", "Eb3"], locations: ["s6f11", "s5f6", "s4f1"]} ,
        { note: ["E3", "Fb3"], locations: ["s6f12", "s5f7", "s4f2"]} ,
        { note: ["F3", "E#3"], locations: ["s6f13", "s5f8", "s4f3"]} ,
        { note: ["F#3", "Gb3"], locations: ["s6f14", "s5f9", "s4f4"]} ,
        { note: ["G3", "F##3"], locations: ["s6f15", "s5f10", "s4f5", "s3f0"]} ,
    ];
    
    function getNoteById(location) {
        let foundLocations = noteLocations.find((e) => e.locations.includes(location));
        if (typeof foundLocations !== "undefined") {
            return foundLocations.note[0];
        } else {
            return "Ø";
        }
    }
    console.log("Note: " + getNoteById('s4f4'));
    
    
    function reusableLookup(search4, objName, param1, param2) {
        let parameterDesc = objName.find((e) => e[param1].includes(search4));
        if (typeof parameterDesc !== "undefined") {
            return parameterDesc[param2][0];
        } else {
            return "Ø";
        }
    }
    console.log("Note: " + reusableLookup('s4f4',noteLocations, 'locations', 'note'));