Требуется общая функция, которая манипулирует объектом и дает требуемый ответ - PullRequest
0 голосов
/ 02 октября 2018

У меня следующий объект JSON:

{
    "$and": [{
        "fname": "test"
    }, {
        "lname": "test1"
    }, {
        "$or": [{
            "age": 20
        }, {
            "address": "mumbai"
        }, {
            "$and": [{
                "fav": "java"
            }, {
                "price": 200
            }]
        }]
    }, {
        "java": "servlet"
    }, {
        "$and": [{
            "colour": "green"
        }, {
            "pin": 400
        }]
    }]
}

Мне нужна функция javascript, которая преобразует ее в следующий формат:

{
    "must": [{
        "fname": "test"
    }, {
        "lname": "test1"
    }, {
        "should": [{
            "age": 20
        }, {
            "address": "mumbai"
        }, {
            "must": [{
                "fav": "java"
            }, {
                "price": 200
            }]
        }]
    }, {
        "java": "servlet"
    }, {
        "must": [{
            "colour": "green"
        }, {
            "pin": 400
        }]
    }]
}

нет ограничений для вложенного массива.так нужна общая функция, которая перебирает входной объект JSON и дает желаемый ответ. Помогите мне в этом?

Ответы [ 4 ]

0 голосов
/ 02 октября 2018

Вы можете использовать lodash _.transform() рекурсивно для замены ключей.Метод будет перебирать все объекты и массивы и заменять все ключи результатом обратного вызова (cb):

const mapKeysDeep = (obj, cb) =>
  _.transform(obj, (result, value, key) => {
    result[cb(key)] = _.isObject(value) ? mapKeysDeep(value, cb) : value;
  });

const obj = {"$and":[{"fname":"test"},{"lname":"test1"},{"$or":[{"age":20},{"address":"mumbai"},{"$and":[{"fav":"java"},{"price":200}]}]},{"java":"servlet"},{"$and":[{"colour":"green"},{"pin":400}]}]};

const replaceMap = new Map([['$and', 'must'], ['$or', 'should']]);

const result = mapKeysDeep(obj, key => replaceMap.get(key) || key);

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
0 голосов
/ 02 октября 2018

Для этого вам понадобится рекурсия.Это должно делать то, что вам нужно.

function findAndReplace(obj, find, replace){
  if(Array.isArray(obj)){
    obj.forEach((_obj) => findAndReplace(_obj, find, replace));  
  }else if(typeof(obj) === 'object'){
    for(var key in obj){
      findAndReplace(obj[key], find, replace);
      if(key === find){
        let temp = obj[key];
        obj[replace] = temp;
        delete obj[key];
      }      
    }
  }
}

let test = {
    "$and": [{
        "fname": "test"
    }, {
        "lname": "test1"
    }, {
        "$or": [{
            "age": 20
        }, {
            "address": "mumbai"
        }, {
            "$and": [{
                "fav": "java"
            }, {
                "price": 200
            }]
        }]
    }, {
        "java": "servlet"
    }, {
        "$and": [{
            "colour": "green"
        }, {
            "pin": 400
        }]
    }]
};
findAndReplace(test, "$and", "must");
findAndReplace(test, "$or", "should")
console.log(test);
0 голосов
/ 02 октября 2018

В вашем случае, я думаю, что лучший способ это примерно так:

let str = JSON.stringify(t1);
str = str.replace(/[$]and/g, 'must');
str = str.replace(/[$]or/g, 'should');
const t2 = JSON.parse(str);

Где t1 - ваш json, а t2 - преобразованный json

0 голосов
/ 02 октября 2018

Самый элегантный способ:

 const output = JSON.parse(
   JSON.stringify(input)
    .replace(/"\$and"/g, `"must"`)
    .replace(/"\$or"/g, `"should"`)
 );

Или чуть менее элегантный:

 const replacer = ({ $and, $or, ...rest }) => ({ must: $and,  should: $or, ...rest });

 const mapDeep = (obj, mapper) => {
   const result = {};
   for(const [key, value] of Object.entries(mapper(obj))) {
     if(Array.isArray(value)) {
       result[key] = value.map(el => typeof el === "object" ? mapDeep(el, mapper) : el);
     } else if(typeof value === "object") {
       result[key] = mapDeep(value, mapper);
     } else {
       result[key] = value;
     }
   }
   return result;
 }

 const output = mapDeep(input, replacer);
...