Home > Back-end >  javascript filter json where data equal value
javascript filter json where data equal value

Time:01-13

I have the follow json object. I am trying to filter through the data and get the socketId value where name is equal to bq89 ```name: "bq89"

const rooms = {
    "room1": {
        "socketId1":{
            id: "123",
            name: "the person name 1"
        },
        "socketId2":{
            id: "bq89",
            name: "the person name 2"
        }
    },
    "room2": {
        "socketId11":{
            id: "jkl",
            name: "room 2 name 1"
        },
        "socketId22":{
            id: "lpo",
            name: "room 2 name 2"
        }
    }
}

const socketId = rooms['room1'].filter(e=> {return e.name === 'bq89'})

console.log(socketId)
// desired output would be: socketId2

CodePudding user response:

Using Object.entries to convert room1 to an array of entries allows you to use Array methods such as Array.find and Array.filter. You say you want to "filter the socketId value where name is equal to bq89" (singular) thus I assume by "filter" you actually mean "find".

const rooms = {
  "room1": {
    "socketId1": {
      id: "123",
      name: "the person name 1"
    },
    "socketId2": {
      id: "bq89",
      name: "bq89"
    }
  },
  "room2": {
    "socketId11": {
      id: "jkl",
      name: "room 2 name 1"
    },
    "socketId22": {
      id: "lpo",
      name: "room 2 name 2"
    }
  }
}

function getSocketId(name) {
  return Object.values(rooms)
    .flatMap(v => Object.entries(v))
    .find(([key, value]) => value.name === name)[0];
}

// desired output would be: socketId2
console.log(getSocketId("bq89"));

More generally, the data you're receiving from the API is broken and unconventionally formatted. If you have access to the API I suggest you change the way the data is structured.

CodePudding user response:

In case was needed to visit the whole rooms object this was my approach that relied on Array.reduce to flatten the initial object.

It doesn't add anything to the accepted answer in terms of fulfilling the expectations. It's actually slower indeed since it performs actions not required.

const rooms = {
    "room1": {
        "socketId1": {
            id: "123",
            name: "the person name 1"
        },
        "socketId2": {
            id: "bq89",
            name: "bq89"
        }
    },
    "room2": {
        "socketId11": {
            id: "jkl",
            name: "room 2 name 1"
        },
        "socketId22": {
            id: "lpo",
            name: "room 2 name 2"
        }
    }
}

//flatten the rooms object
//returning a single object where the props are the socketids with their corresponding values
const sockets = Object.entries(rooms).reduce( (merge,[roomname, sockets])=>{ return {...sockets, ...merge} }, {} );

function findSocketsIdByName(name){
  //returns an array where each item is a socket being an array of 2 elements [socketid,{...props}]
  const socketsFound = Object.entries(sockets).filter( ([socketid, props]) => props.name == name);
  //returns an array with only the socketid of the object matching the wanted name
  const socketsIdFound = socketsFound.map( socket => socket[0]);

  return socketsIdFound;
}

let idFound;

idFound = findSocketsIdByName('bq89');
console.log(idFound);

idFound = findSocketsIdByName('room 2 name 2');
console.log(idFound);

  • Related