Home > Software engineering >  Filtering Objects Inside Another Object
Filtering Objects Inside Another Object

Time:09-11

I have a object, 'docs', that is composed of objects inside of it. I trying to get a count of the number entries that have a certain value for 'exopp_rooms_id_c' and 'is_active'. This is probably really simple but I just can't seem to figure it out.

"docs": {
    "0a0c45ef-2694-a081-a57c-3ea281c3a45f":{
        "name":"ccc",
        "exopp_rooms_id_c":"d13fd59f-5e67-06df-bd11-7f6e0892cbb1",
        "is_active":"Yes"},
    "0a0faf41-dc42-80f6-b614-af344df91d62":{
        "name":"bbb",
        "exopp_rooms_id_c":"d13fd59f-5e67-06df-bd11-7f6e0892cbb1",
        "is_active":"No"},
    "0a1d57c8-aef0-8d37-9da1-3d54c37e0022":{
        "name":"aaa",
        "exopp_rooms_id_c":"3bd54fdd-fe7d-e7a2-4791-12e0ed93df3e",
        "is_active":"Yes"}
}

CodePudding user response:

I believe this will give a hint.

const data = {
  docs: {
    '0a0c45ef-2694-a081-a57c-3ea281c3a45f': {
      name: 'ccc',
      exopp_rooms_id_c: 'd13fd59f-5e67-06df-bd11-7f6e0892cbb1',
      is_active: 'Yes',
    },
    '0a0faf41-dc42-80f6-b614-af344df91d62': {
      name: 'bbb',
      exopp_rooms_id_c: 'd13fd59f-5e67-06df-bd11-7f6e0892cbb1',
      is_active: 'No',
    },
    '0a1d57c8-aef0-8d37-9da1-3d54c37e0022': {
      name: 'aaa',
      exopp_rooms_id_c: '3bd54fdd-fe7d-e7a2-4791-12e0ed93df3e',
      is_active: 'Yes',
    },
  },
};

for (const [key, subObjcet] of Object.entries(data.docs)) {
  console.log(key, subObjcet);
}

CodePudding user response:

You can use Object.values to iterate over values of an object. Hence, you can use filter to get the values that match a given predicate and then use length to count the number of objects found.

In your case:

function countActiveItems(obj): number {
  return Object.values(obj).filter(value => value.is_active === 'Yes').length;
}

If you want a more complex check, for example - checking if the item is active AND has a certain name or id - just extend the conditional on the filter callback.

CodePudding user response:

Since you tagged Typescript, the first thing is do is type your object:

/** Typescript */
type yesOrNo = 'No' | 'Yes'

interface IRoom {
    name: string
    exopp_rooms_id_c: string
    is_active: yesOrNo
}

interface IDocs { [key: string]: IRoom }
/***************/

const data: { docs: IDocs } = {
  docs: {
    '0a0c45ef-2694-a081-a57c-3ea281c3a45f': {
      name: 'ccc',
      exopp_rooms_id_c: 'd13fd59f-5e67-06df-bd11-7f6e0892cbb1',
      is_active: 'Yes',
    },
    '0a0faf41-dc42-80f6-b614-af344df91d62': {
      name: 'bbb',
      exopp_rooms_id_c: 'd13fd59f-5e67-06df-bd11-7f6e0892cbb1',
      is_active: 'No',
    },
    '0a1d57c8-aef0-8d37-9da1-3d54c37e0022': {
      name: 'aaa',
      exopp_rooms_id_c: '3bd54fdd-fe7d-e7a2-4791-12e0ed93df3e',
      is_active: 'Yes',
    },
  },
};

/**
 * 
 * General filter for room
 * 
 * To return true:
 *      - `exopp_rooms_id_c` must equal `exoppCriteria`
 *      - `is_active` must equal `isActive` (default 'Yes')
 * 
 * @returns boolean
 */
function exoppRoomFilter(
    room: IRoom, 
    exoppCriteria: string, 
    isActive: yesOrNo = 'Yes'
): boolean { 
    return (
        room.exopp_rooms_id_c === exoppCriteria && 
        room.is_active === isActive
    )
}

const exoppCriteria = 'd13fd59f-5e67-06df-bd11-7f6e0892cbb1'
const specificFilter = (room: IRoom) => exoppRoomFilter(room, exoppCriteria)

const noOfRooms = Object.values(data.docs).filter(specificFilter).length;

console.log(noOfRooms)

CodePudding user response:

You may use the following

function countItems(obj): number {
      return Object.values(obj).filter(value => (value.is_active === 'Yes' && value.exopp_rooms_id_c)).length;
    }
  • Related