Skip to content

Instantly share code, notes, and snippets.

@waptik
Last active May 8, 2021 04:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save waptik/795708293e442e3f0ee0c63f40552b78 to your computer and use it in GitHub Desktop.
Save waptik/795708293e442e3f0ee0c63f40552b78 to your computer and use it in GitHub Desktop.
[SOLVED] - I need help to: 1: rename keys to lowercase values 2: remove empty objects with one non-null key
// current code
const arrs = [
{
comments: 'asd',
movement: 'Back Squat',
userID: 'wDHZv3OL55SIymHkhMUejNleNkx1',
weight: '330',
},
{
comments: 'asd',
movement: 'Bench Press',
userID: 'wDHZv3OL55SIymHkhMUejNleNkx1',
weight: '100',
},
{
comments: 'Comment',
movement: 'Clean',
userID: 'wDHZv3OL55SIymHkhMUejNleNkx1',
weight: '195',
},
{
comments: 'Front squat comment alpha',
movement: 'Front Squat',
userID: 'wDHZv3OL55SIymHkhMUejNleNkx1',
weight: '315',
},
{
comments: 'egg',
movement: 'Strict',
userID: 'wDHZv3OL55SIymHkhMUejNleNkx1',
weight: '155',
},
{ comments: 'sleep', movement: null, userID: null, weight: null },
{ comments: 'look', movement: null, userID: null, weight: null },
{
comments: 'abc',
movement: 'Strict Press',
userID: 'wDHZv3OL55SIymHkhMUejNleNkx1',
weight: '155',
},
];
// expected output
// 1.
const arrs = [
{
comments: 'asd',
movement: 'Back Squat',
userid: 'wDHZv3OL55SIymHkhMUejNleNkx1',
weight: '330',
},
{
comments: 'asd',
movement: 'Bench Press',
userid: 'wDHZv3OL55SIymHkhMUejNleNkx1',
weight: '100',
},
{
comments: 'Comment',
movement: 'Clean',
userid: 'wDHZv3OL55SIymHkhMUejNleNkx1',
weight: '195',
},
{
comments: 'Front squat comment alpha',
movement: 'Front Squat',
userid: 'wDHZv3OL55SIymHkhMUejNleNkx1',
weight: '315',
},
{
comments: 'egg',
movement: 'Strict',
userid: 'wDHZv3OL55SIymHkhMUejNleNkx1',
weight: '155',
},
{ comments: 'sleep', movement: "N/A", userid: "N/A", weight: "N/A" },
{ comments: 'look', movement: "N/A", userid: "N/A", weight: "N/A" },
{
comments: 'abc',
movement: 'Strict Press',
userid: 'wDHZv3OL55SIymHkhMUejNleNkx1',
weight: '155',
},
];
// or 2.
const arrs = [
{
comments: 'asd',
movement: 'Back Squat',
userid: 'wDHZv3OL55SIymHkhMUejNleNkx1',
weight: '330',
},
{
comments: 'asd',
movement: 'Bench Press',
userid: 'wDHZv3OL55SIymHkhMUejNleNkx1',
weight: '100',
},
{
comments: 'Comment',
movement: 'Clean',
userid: 'wDHZv3OL55SIymHkhMUejNleNkx1',
weight: '195',
},
{
comments: 'Front squat comment alpha',
movement: 'Front Squat',
userid: 'wDHZv3OL55SIymHkhMUejNleNkx1',
weight: '315',
},
{
comments: 'egg',
movement: 'Strict',
userid: 'wDHZv3OL55SIymHkhMUejNleNkx1',
weight: '155',
},
{
comments: 'abc',
movement: 'Strict Press',
userid: 'wDHZv3OL55SIymHkhMUejNleNkx1',
weight: '155',
},
];
@waptik
Copy link
Author

waptik commented May 7, 2021

Here's what i've done so far:

arrs
      .map((value: any) => {
        const x = Object.entries(value)
          .map((entry) => {
            const key = entry[0].toLowerCase();
            const val = entry[1];
            const obj = { [key]: val };

            if (key === 'no') delete obj[key];
            return obj;
          })
          .filter(
            (s) =>
              s[keys[0]] !== null && s[keys[1]] !== null && s[keys[2]] !== null
          )
          .filter((s) => Object.keys(s).length);

        return x;
      })
      .filter((d) => d.length);

The outcome of it, isn't what i want.

@waptik
Copy link
Author

waptik commented May 8, 2021

Snippet has been updated with expected outputs. I prefer output no. 2

@KnightNiwrem
Copy link

KnightNiwrem commented May 8, 2021

Personally, I would filter first (just because it is easier to work with objects), then reformat the objects with map.

arrs
  .filter(obj => (
    Object
      .values(obj)
      .every(val => val !== null)
  ))
  .map(obj => Object.fromEntries(
    Object
      .entries(obj)
      .map(([k, v]) => [k.toLowerCase(), v])
      .filter(([k, v]) => k !== 'no')
  ));

@waptik
Copy link
Author

waptik commented May 8, 2021

Another scenario

const arrs = [
  {
    comments: 'asd',
    name: 'joe',
    movement: 'Back Squat',
    userid: 'wDHZv3OL55SIymHkhMUejNleNkx1',
    weight: '330',
  },
  {
    comments: 'asd',
    name: 'cardi',
    movement: 'Bench Press',
    userid: 'wDHZv3OL55SIymHkhMUejNleNkx1',
    weight: '100',
  },
  {
    comments: 'Comment',
    name: 'joseph',
    movement: 'Clean',
    userid: 'wDHZv3OL55SIymHkhMUejNleNkx1',
    weight: '195',
  },
  {
    comments: 'Front squat comment alpha',
    name: 'joy',
    movement: 'Front Squat',
    userid: 'wDHZv3OL55SIymHkhMUejNleNkx1',
    weight: '315',
  },
  {
    comments: 'egg',
    name: 'may',
    movement: 'Strict',
    userid: 'wDHZv3OL55SIymHkhMUejNleNkx1',
    weight: '155',
  },
  {
    comments: 'abc',
    name: 'santi',
    movement: 'Strict Press',
    userid: 'wDHZv3OL55SIymHkhMUejNleNkx1',
    weight: '155',
  },
  { comments: null, name:'silver', movement: null, userID: null, weight: null }, // keep only name

  { comments: null, name:null, movement: null, userID: null, weight: null }, // object to be remove
];

@KnightNiwrem
Copy link

The original filter removes any object as long as it has a single null value. In this change, there are objects that may have null values that we want to keep now, so we need to change our approach.

Since our filter step is going to filter by a certain key now, I would move the map in front of the filter, just so I can standardise (lowercase) the keys early. In fact, any checks against key is best done after we have lowercased the keys.

Hence, our approach will take 3 steps:

  1. Lowercase all keys, and remove the no key
  2. Keep objects only if
    a. it has a defined, non-null value for name
    b. all values are non-null
  3. Clean up non-null key-value pairs that remain (i.e. the object had a defined, non-null name property, and was not a candidate for removal)
arrs
  .map(obj => Object.fromEntries(
    Object
      .entries(obj)
      .map(([k, v]) => [k.toLowerCase(), v])
      .filter(([k, v]) => k !== 'no')
  ))
  .filter(obj => (
    (obj['name'] !== null && obj['name'] !== undefined) || Object.values(obj).every(v => v !== null)
  ))
  .map(obj => Object.fromEntries(
    Object
      .entries(obj)
      .filter(([k, v]) => v !== null)
  ));

@waptik
Copy link
Author

waptik commented May 8, 2021

The original filter removes any object as long as it has a single null value. In this change, there are objects that may have null values that we want to keep now, so we need to change our approach.

Since our filter step is going to filter by a certain key now, I would move the map in front of the filter, just so I can standardise (lowercase) the keys early. In fact, any checks against key is best done after we have lowercased the keys.

Hence, our approach will take 3 steps:

  1. Lowercase all keys, and remove the no key
  2. Keep objects only if
    a. it has a defined, non-null value for name
    b. all values are non-null
  3. Clean up non-null key-value pairs that remain (i.e. the object had a defined, non-null name property, and was not a candidate for removal)
arrs
  .map(obj => Object.fromEntries(
    Object
      .entries(obj)
      .map(([k, v]) => [k.toLowerCase(), v])
      .filter(([k, v]) => k !== 'no')
  ))
  .filter(obj => (
    (obj['name'] !== null && obj['name'] !== undefined) || Object.values(obj).every(v => v !== null)
  ))
  .map(obj => Object.fromEntries(
    Object
      .entries(obj)
      .filter(([k, v]) => v !== null)
  ));

Thanks again! I really appreciate it.

Origial
After applying your code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment