1

I would like to be able to replace certain keys within an object of dynamic size using Javascript. For example, I have an object that might look like this:

var obj = {
    where: {
        hypes: {
            lte: 12 <-- replace key
        },
        or: [
            {
                hypes: {
                    lt: 14 <-- replace key
                }
            },
            {
                id: {
                    lt: 10 <-- replace key
                }
            }
        ]
    } 
}

In order for this object to be used with Sequelize I need to convert the following keys to Sequelize operators: lt, or, and lte. I've created an operators object that acts as a dictionary so I can pull the Sequelize operator from it:

const operators = {
    'eq': [Op.eq],
    'lte': [Op.lte],
    'lt': [Op.lt],
    'or': [Op.or]
};

I was thinking I could use the operators object to match the key of the obj and replace it with the value of the operators object. I figured I could use the following recursive function to loop through the obj given its unknown size:

const iterate = (obj) => {
    Object.keys(obj).forEach(key => {

    console.log(`key: ${key}, value: ${obj[key]}`)

    if (typeof obj[key] === 'object') {
            iterate(obj[key])
        }
    })
}

The above function will check if the value of a key is an object and will call the iterate() method again.

Thus I can call: iterate(obj) and it'll recursively map through all nested properties in the object.

The issue I am having is how do I replace the keys when they match a property inside the operators object so that I'll end up with an obj that looks like this:

var obj = {
    where: {
        hypes: {
            lte: 12
        },
        [Op.or]: [ <-- changed
            {
                hypes: {
                    [Op.lt]: 14 <-- changed
                }
            },
            {
                id: {
                    [Op.lt]: 10 <-- changed
                }
            }
        ]
    } 
}

Thanks!

2 Answers 2

1

You could take a recursive approach.

function replace(object) {
    return Array.isArray(object)
        ? object.map(replace)
        : object && typeof object === 'object'
            ? Object.fromEntries(Object
                .entries(object)
                .map(([k, v]) => [k in operators ? operators[k] : k, replace(v)])
            )
            : object;
}

var obj = { where: { hypes: { lte: 12 }, or: [{ hypes: { lt: 'xx' } }, { id: { lt: 10 } }] } };

const operators = { eq: '[Op.eq]', lte: '[Op.lte]', lt: '[Op.lt]', or: '[Op.or]' };

console.log(replace(obj));

Sign up to request clarification or add additional context in comments.

1 Comment

Love this recursive approach! Thank you so much, small typo in the answer though. There should be a semicolon after the obj instead of a comma. Anyways this had me stumped, I appreciate the help!
0

In your recursive function when you hit the leaf, you can change the key and delete the older one.

var obj = {
  where: {
    hypes: {
      lte: 12
    },
    or: [{
        hypes: {
          lt: 14
        }
      },
      {
        id: {
          lt: 10
        }
      }
    ]
  }
};

const operators = {
  eq: '[Op.eq]',
  lte: '[Op.lte]',
  lt: '[Op.lt]',
  or: '[Op.or]'
};

const iterate = (obj) => {
  Object.keys(obj).forEach(key => {
    // console.log(`key: ${key}, value: ${obj[key]}`)
    if (typeof obj[key] === 'object') {
      iterate(obj[key])
    }
    if (operators[key]) {
      obj[operators[key]] = obj[key];
      delete obj[key];
    }
  });
};

iterate(obj)
console.log(obj)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.