0

I have a mapping as shown below, and i want to pass 1 to a function and get key a back or also pass key "a" and then get value 1 back. what is a best way to do this via plain javascript?

const somemap = {"a": 1, "b": 2, "c": 3};

arve
  • 569
  • 2
  • 10
  • 27
  • 1
    there's a way but in terms of compromise.. since that won't be a key, the most you can expect is returning the first property found having such value – Diego D Jan 16 '23 at 21:00
  • Are values going to be unique? i.e. Should it be impossible to do something like this: `const somemap = {"a": 1, "b": 1, "c": 3};` – Tibrogargan Jan 16 '23 at 21:04
  • @Tibrogargan - yes values will be always unique. – arve Jan 16 '23 at 21:07
  • Please update the question - this is a new requirement and very definitely will change the answer. You should also clarify if you need one function that returns a result given either a key or a value, or if two functions are ok. – Tibrogargan Jan 16 '23 at 21:12

2 Answers2

2

To fulfill the conditions stated as:

"and i want to pass 1 to a function and get key a back or also pass key "a" and then get value 1 back"

I defined the function as $(obj, {needle, findAsKey = false, findAsValue = false})

where:

  • obj - is the object target of the search
  • {needle} - the search term supposedly a string when searched as key and anything else when searched as value.
  • {findAsKey} - a boolean flag stating if we are willing to search for the needle as a key in the obj object. The default value is false
  • {findAsValue} - a boolean flag stating if we are willing to search for the needle as a value in the obj object. The default value is false.

The function returns an object containing the following properties:

  • needle: the term used for the search in the target object.

  • asKey: when needle is used as key in the given array.

This property is set if the passed findAsKey was true and if the key was present in the target object. If the key was found, asKey can have any value including null, undefined, Array, Object...

  • asValue: when needle is used as value in the given array (first prop found if any).

This property is set if the passed findAsValue flag was true and if the value was present in the target object. When the needle was found as a property value, asValue is expected to return a legit property name so its value can only be a valid identifier (not undefined or null but a string holding the js constraints).

const somemap = {"a": 1, "b": [1,2,3], "c": 3};

console.log( $(somemap, {needle: 'a', findAsKey: true}) );
console.log( $(somemap, {needle: 'a', findAsValue: true}) );

console.log( $(somemap, {needle: 1, findAsKey: true}) );
console.log( $(somemap, {needle: 1, findAsValue: true}) );

console.log( $(somemap, {needle: 'c', findAsKey: true, findAsValue: true}) );
console.log( $(somemap, {needle: 'c', findAsKey: true, findAsValue: true}) );

console.log( $(somemap, {needle: "", findAsKey: true, findAsValue: true}) );
console.log( $(somemap, {needle: null, findAsKey: true, findAsValue: true}) );
console.log( $(somemap, {needle: undefined, findAsKey: true, findAsValue: true}) );

function $(obj, {needle, findAsKey = false, findAsValue = false}){
   
  const result = {needle, findAsKey, findAsValue};
  
  //set .asKey only if it was meant to be found as key
  //and the property exists in obj
  if(findAsKey && needle in obj)
    result.asKey = obj[needle];
  
  //if it was meant to be found as value
  if(findAsValue){
    //fetch the first propertyName found having that value
    const asValue = ((needle)=>{
      for([key, value] of Object.entries(obj))
        if(value === needle)
          return {result: key};
    })(needle);
    //set .asValue only if asValue was actually found
    if(asValue !== undefined)
      result.asValue = asValue.result; //no pun intended
  }
    
  return result;
}
Diego D
  • 6,156
  • 2
  • 17
  • 30
0

More time consuming, less memory consuming

const somemap = {"a": 1, "b": 2, "c": 3};

console.log(getValue('b'))
console.log(getKey(2))

function getValue(key) {
  return somemap[key]
}

function getKey(value) {
  return Object.entries(somemap).find(([key, val]) => val === value)[0]
}

Less time consuming, more memory consuming

const somemap = {"a": 1, "b": 2, "c": 3};
const mapsome = invert(somemap)

console.log(getValue('b'))
console.log(getKey(2))

function getValue(key) {
  return somemap[key]
}

function getKey(value) {
  return mapsome[value]
}

function invert(obj) {
  return Object.fromEntries(Object.entries(obj).map(([key, value]) => [value, key]))
}
Konrad
  • 21,590
  • 4
  • 28
  • 64
  • Doesn't meet requirements: It's implied that it's a single function, not two. – Tibrogargan Jan 16 '23 at 21:05
  • @Tibrogargan you can be right, but the question doesn't make it clear that it has to be one function – Konrad Jan 16 '23 at 21:08
  • 1
    I'd tend to agree. It sounds like they want a single function - but definitely a place where requirements should have been clarified before delivering a product, no? (OP just went and changed requirements too) – Tibrogargan Jan 16 '23 at 21:10