简体   繁体   English

使用Javascript递归替换未知大小的对象中的键

[英]Recursively replace keys within an object of unknown size using Javascript

I would like to be able to replace certain keys within an object of dynamic size using Javascript.我希望能够使用 Javascript 替换动态大小对象中的某些keys 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 .为了将此对象与Sequelize一起使用,我需要将以下键转换为Sequelize运算符: ltorlte I've created an operators object that acts as a dictionary so I can pull the Sequelize operator from it:我创建了一个作为字典的operators对象,所以我可以从中提取Sequelize操作符:

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.我在想我可以使用operators对象来匹配obj的键并将其替换为operators对象的值。 I figured I could use the following recursive function to loop through the obj given its unknown size:我想我可以使用以下递归函数来循环遍历obj给定的未知大小:

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.上面的函数将检查一个键的值是否是一个对象,并会再次调用iterate()方法。

Thus I can call: iterate(obj) and it'll recursively map through all nested properties in the object.因此我可以调用: iterate(obj)它将递归映射对象中的所有嵌套属性。

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:我遇到的问题是如何在键与operators对象内的属性匹配时替换键,以便我最终得到一个如下所示的obj

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

Thanks!谢谢!

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));

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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM