简体   繁体   中英

Return key of object whose value is an object that contains a property that matches a condition

I have an object

const CABLE_SOURCES = {
    foxnews: {
        id: "FOXNEWSW",
        name: "Fox News",
    },
    cnn: {
        id: "CNNW",
        name: "CNN",
    },
    msnbc: {
        id: "MSNBCW",
        name: "MSNBC",
    },
    abc7: {
        id: "KGO",
        name: "ABC 7 news",
    },
};

My current solution looks something like

function getKeyName(cableSourceId) {
    let source = null;
    for (let s in CABLE_SOURCES) {
        if (CABLE_SOURCES[s].id === cableSourceId) {
            source = s;
        }
        break;
    }
    return source;
}

getKeyName("FOXNEWSW")
// foxnews

Is there a more functional / elegant way to rewrite getKeyName , either with ES6, or lodash?

One option is to .find one of the object's entries whose value has that id . If such an entry is found, return the first item in it (the key), otherwise return null :

 const CABLE_SOURCES = { foxnews: { id: "FOXNEWSW", name: "Fox News", }, cnn: { id: "CNNW", name: "CNN", }, msnbc: { id: "MSNBCW", name: "MSNBC", }, abc7: { id: "KGO", name: "ABC 7 news", }, }; function getKeyName(cableSourceId) { const foundEntry = Object.entries(CABLE_SOURCES).find(([, { id }]) => id === cableSourceId); return foundEntry ? foundEntry[0] : null; } console.log(getKeyName("FOXNEWSW")); console.log(getKeyName("foo"));

I guess you can use Object.keys() and Array.prototype.find() combination. Once you have the found object, just need to access name property.

Object.keys() documentation states:

The Object.keys() method returns an array of a given object's own enumerable property names, in the same order as we get with a normal loop.

Array.prototype.find() documentation states:

The find() method returns the value of the first element in the provided array that satisfies the provided testing function.

Like the following:

 const CABLE_SOURCES = { foxnews: { id: "FOXNEWSW", name: "Fox News", }, cnn: { id: "CNNW", name: "CNN", }, msnbc: { id: "MSNBCW", name: "MSNBC", }, abc7: { id: "KGO", name: "ABC 7 news", }, }; const getKeyName = text => CABLE_SOURCES[Object.keys(CABLE_SOURCES).find(i => CABLE_SOURCES[i].id === text)].name; const result = getKeyName("FOXNEWSW"); console.log(result);

I hope that helps!

Lodash has a _.findKey() method that accepts a predicate (object in this case), and returns the 1st key with a value that matches the predicate:

 function getKeyName(id) { return _.findKey(CABLE_SOURCES, { id }); } const CABLE_SOURCES = {"foxnews":{"id":"FOXNEWSW","name":"Fox News"},"cnn":{"id":"CNNW","name":"CNN"},"msnbc":{"id":"MSNBCW","name":"MSNBC"},"abc7":{"id":"KGO","name":"ABC 7 news"}}; console.log(getKeyName("FOXNEWSW")); console.log(getKeyName("foo"));
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM