skip to Main Content

I need to create a new array by filtering the data.

{
  "roles": [
    {
      "role": "manager",
      "test_id": "123"
    },
    {
      "role": "cashier",
      "test_id": "123"
    },
    {
      "role": "customer",
      "test_id": "123"
    },
    {
      "role": "cashier_2",
      "test_id": "500"
    }
  ],
}

I need to filter this array and create a new array by using the test_id this is the expected format.

{
  "roles": [
    {
      "role": [manager, cashier, customer],
      "test_id": "123"
    },
    {
      "role": "cashier_2",
      "test_id": "500"
    }
  ],
}

I tried using the filter method and using the map method but couldn’t get the expected output.

  let x = [];

   const test = userRoles?.map((item, index, element) => {
     let next = element[index+1];
        if(item?.test_id == next?.test_id){
            x.push(item?.role)   
         }
     })

3

Answers


  1. I don’t think map() works here, as it just maps entries to (new) entries, but you need to group them. This is a job for reduce(), which lets you create anything out of the entries.

    In this case, an object for easy lookup between test_id and grouped entries works well:

    const data = {
      "roles": [
        {
          "role": "manager",
          "test_id": "123"
        },
        {
          "role": "cashier",
          "test_id": "123"
        },
        {
          "role": "customer",
          "test_id": "123"
        },
        {
          "role": "cashier_2",
          "test_id": "500"
        }
      ],
    }
    
    const res = Object.values(data.roles.reduce((groups, entry) => {
        groups[entry.test_id] ??= {test_id: entry.test_id, role: []}
        groups[entry.test_id].role.push(entry.role)
        return groups
      },{})
    )
    
    console.log(res)
    Login or Signup to reply.
  2. To create the desired new array from the existing array, you can use the reduce() method to iterate through the roles and group them by their test_id. For each role, you can check if there is already an object in the accumulator array with the same test_id. If there is, you can push the role to the existing object’s role array. If there isn’t, you can create a new object with the test_id and an array containing the role, and push it to the accumulator array. Here’s some code that should do the trick:

    const roles = [
      {
        "role": "manager",
        "test_id": "123"
      },
      {
        "role": "cashier",
        "test_id": "123"
      },
      {
        "role": "customer",
        "test_id": "123"
      },
      {
        "role": "cashier_2",
        "test_id": "500"
      }
    ];
    
    const groupedRoles = roles.reduce((accumulator, role) => {
      const existingGroup = accumulator.find(group => group.test_id === role.test_id);
      
      if (existingGroup) {
        existingGroup.role.push(role.role);
      } else {
        accumulator.push({
          test_id: role.test_id,
          role: [role.role]
        });
      }
      
      return accumulator;
    }, []);
    
    console.log(groupedRoles);
    

    This should output:

    [  {    "test_id": "123",    "role": ["manager", "cashier", "customer"]
      },
      {
        "test_id": "500",
        "role": ["cashier_2"]
      }
    ]
    

    Note that the code assumes that the roles array is already sorted by test_id. If that’s not the case, you can use the sort() method to sort it first. Also, I’ve used console.log() to show the result, but you can return the groupedRoles array from a function or use it in some other way as needed.

    Login or Signup to reply.
  3. You could use Object.entries() in combination with Array#reduce() and Array#map() methods as follows:

    const 
          input = { "roles": [ { "role": "manager", "test_id": "123" }, { "role": "cashier", "test_id": "123" }, { "role": "customer", "test_id": "123" }, { "role": "cashier_2", "test_id": "500" } ] },
          
          output = {
            roles: Object.entries(
              input.roles.reduce(
                (acc,cur,index) => ({
                    ...acc,[cur.test_id]:acc[cur.test_id] ?
                    [...[acc[cur.test_id]].flat(),cur.role] : cur.role
                }), {}
              )
            )
            .map(
              ([test_id, role]) =>
              ({role, test_id})
            )
          };
    
    console.log( output );
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search