如何在多个对象中插入具有动态值的属性或在多个数组中动态添加元素? [英] How to insert a attribute with a dynamic value in many object or add an element dynamically in many array?

查看:134
本文介绍了如何在多个对象中插入具有动态值的属性或在多个数组中动态添加元素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在许多对象(位于数组中)中添加一个属性,并且该值将动态获取.我使用下面的JSON,并且已经进行了查询以提取所需的内容.我们将从该查询的结果开始.

I want to add an attribute in many object(situated in an array) and this value will be get dynamically. I use the JSON below, and I already made a query to extract what I want. We will start with th result of this query.

首先是我的整个JSON:

First my entire JSON:

[  
   {  
      "Nature":"lol",
      "EV":"lol",
      "Moves":[  
         {  
"Move":"OHKOmove",
            "Max":100,
            "Min":15
         },
         {  
"Move":"cacaz",
            "Max":35,
            "Min":20
         }
      ]
   },
   {  
      "Nature":"loi",
      "EV":"lal",
      "Moves":[  
         {  
"Move":"caca1",
            "Max":100,
            "Min":3
         },
{  
"Move":"caca2",
            "Max":100,
            "Min":3
         }
      ]
   },
   {  
      "Nature":"loi2",
      "EV":"lal",
      "Moves":[  
         {  
"Move":"caca1",
            "Max":100,
            "Min":3
         },
{  
"Move":"caca2",
            "Max":100,
            "Min":3
         },
{  
"Move":"caca3",
            "Max":100,
            "Min":3
         }
      ]
   },
   {  
      "Nature":"loi3",
      "EV":"lil",
      "Moves":[  
         {  
"Move":"caca1",
            "Max":100,
            "Min":3
         },
{  
"Move":"caca2",
            "Max":100,
            "Min":3
         },
{  
"Move":"caca3",
            "Max":100,
            "Min":3
         }
      ]
   }
]

然后我的查询:[?(length(Moves[?Max == `100`]) > `1`)].{Nature: Nature, EV: EV, Moves: Moves[?Max == `100`].Move, MovesCount: length(Moves[?Max == `100`].Move)} | [@,{MaxMouvCount: max_by(@, &MovesCount).MovesCount}][]

查询的结果如下:

[
 {
   "Nature": "loi",
   "EV": "lal",
   "Moves": [
     "caca1",
     "caca2"
   ],
   "MovesCount": 2
 },
 {
   "Nature": "loi2",
   "EV": "lal",
   "Moves": [
     "caca1",
     "caca2",
     "caca3"
   ],
   "MovesCount": 3
 },
 {
   "Nature": "loi3",
   "EV": "lil",
   "Moves": [
     "caca1",
     "caca2",
     "caca3"
   ],
   "MovesCount": 3
 },
 {
   "MaxMouvCount": 3
 }
]

想法是将属性"MaxMouvCount": 3放在数组中的每个对象上,然后将其从数组中删除以得到如下结果:

The idea is to put the attribute "MaxMouvCount": 3 on each objects in the array and then delete it from the array to give a result like this:

[
  {
    "Nature": "loi",
    "EV": "lal",
    "Moves": [
      "caca1",
      "caca2"
    ],
    "MovesCount": 2,
    "MaxMouvCount": 3
  },
  {
    "Nature": "loi2",
    "EV": "lal",
    "Moves": [
      "caca1",
      "caca2",
      "caca3"
    ],
    "MovesCount": 3,
    "MaxMouvCount": 3
  },
  {
    "Nature": "loi3",
    "EV": "lil",
    "Moves": [
      "caca1",
      "caca2",
      "caca3"
    ],
    "MovesCount": 3,
    "MaxMouvCount": 3
  }
]

在标题中我谈到了数组,实际上是在查询后使用.*可以转换数组中的对象,并且可以更容易地将每个数组中的值(与对象匹配)并使用对象构造函数将数组重新转换为对象.但是我不知道该怎么做.你能帮我还是至少告诉我可能的话.

In the title I talk about array, in fact with .* after my query I can transform the object in array and maybe put more easier the value in each array(matching with objects) and retransform array into object with object constructor. But I don't know how to do it. Can you help me please or tell me at least if it's possible.

PS:我只使用JMESPath,所以我不希望使用任何其他包含JMESPath代码的语言(例如javascript(就我而言)或python或其他东西)来回答

PS: I use only JMESPath so I don't want an answer with any other language which contains JMESPath code(like javascript(in my case) or python or something else)

推荐答案

快速解答(TL; DR)

  • 通常,使用JMESPath轻松转换JSON很容易
    • 一个轻松的键是利用经过专门规范化的JSON结构,以最佳地与JMESPath结合使用
    • 一个轻松的键是知道何时在JSON中使用字典(又称对象//关联数组//映射)名称/值对,以使JSON的所有部分都能明确引用
    • Quick Answer (TL;DR)

      • Usually it is easy to painlessly transform JSON with JMESPath
        • One pain-free key is to utilize JSON structures that are specifically normalized for optimal use with JMESPath
        • One pain-free key is knowing when to use dictionary (aka objects // associative-arrays // mappings) name-value pairs in your JSON to make all parts of the JSON capable of unambiguous reference
          • JMESPath查询语言
          • python 3.x使用JMESPath 0.9.4 [但是任何JMESPath引擎都可以使用]
          • JMESPath query language
          • python 3.x using JMESPath 0.9.4 [but any JMESPath engine will do]
          • 场景:
            • DeveloperSObosskay972希望将JSON数据从一种表示形式转换为另一种表示形式
            • DeveloperSObosskay972希望仅依靠JMESPath表达式来完成转换
            • DeveloperSObosskay972希望在另一部分中引用JSON结构的一部分,以允许对数据结构进行动态交叉引用
            • Scenario:
              • DeveloperSObosskay972 wishes to transform JSON data from one representation to another
              • DeveloperSObosskay972 wants to rely solely on JMESPath expressions to complete the transformation
              • DeveloperSObosskay972 wants to refer to one part of the JSON structure in another part, to allow for dynamic cross-referencing of the datastructure
              • 不是我们想要的几乎"解决方案
              • 此代码...
              import jmespath
              vdata001aa = """<<json.load(JSON Format Example 1)>>"""
              vresult = jmespath.compile('@|[*].{"Nature":@.Nature,"EV":@.EV,"Moves":@.Moves,"MovesCount":@.MovesCount,"MaxMouvCount":`3`}').search(vdata001aa)
              pprint.pprint(vresult)
              

              • 产生此结果...
              • [{'EV': 'lal',
                  'MaxMouvCount': 3,
                  'Moves': ['caca1', 'caca2'],
                  'MovesCount': 2,
                  'Nature': 'loi'},
                 {'EV': 'lal',
                  'MaxMouvCount': 3,
                  'Moves': ['caca1', 'caca2', 'caca3'],
                  'MovesCount': 3,
                  'Nature': 'loi2'},
                 {'EV': 'lil',
                  'MaxMouvCount': 3,
                  'Moves': ['caca1', 'caca2', 'caca3'],
                  'MovesCount': 3,
                  'Nature': 'loi3'},
                 {'EV': None,
                  'MaxMouvCount': 3,
                  'Moves': None,
                  'MovesCount': None,
                  'Nature': None}]
                

                • 这不是我们想要的,因为:
                  • 我们必须为MaxMouvCount的值3硬连线,这在技术上是作弊"
                    • 之所以作弊是因为我们想要一个 dynamic 值,而不是一个 hard-wired
                      • This is not what we want, because:
                        • we had to hardwire the value 3 for MaxMouvCount which is technically "cheating"
                          • it's cheating because we want a dynamic value, not a hard-wired value
                            • Attempt 01不能正常工作的原因是,原始的JSON结构未针对JMESPath进行规范化
                            • 为了解决这个问题,我们将字典名称/值对添加到原始数据中
                            • 通过这种方法,我们使JSON数据的每个元素成为附加在字典键上的值(又称为javascript对象名称-值对)
                              • 这里我们使用术语dictionary,在其他情况下也称为objecthashassociative arraymapping
                              • 我们不在乎术语,而是能够将顶级JSON的所有部分称为名称/值对
                              • The reason why Attempt 01 does not work well is because the original JSON stucture is not well-normalized for JMESPath
                              • In order to address this, we add dictionary name-value pairs to the original data
                              • With this approach, we make every element of the JSON data a value attached to a dictionary key (aka javascript object name-value pairs)
                                • Here we use the term dictionary which is known in other contexts as object or hash or associative array or mapping
                                • We don't care about the terminology, so much as the ability to refer to all parts of the top-level JSON as name-value pairs
                                • 重新格式化您的原始JSON JSON Format Example 1,因此看起来像这样
                                • 经过重新格式化的JSON将使您数据的所有部分都明确可访问
                                • reformat your original JSON JSON Format Example 1 so it looks like this instead
                                • this reformatted JSON will make all parts of your data unambiguously addressible
                                {
                                "jsontop": {
                                    "settings_info": {
                                      "MaxMouvCount": 3
                                    },
                                    "nature_table": [
                                     {
                                       "Nature": "loi",
                                       "EV": "lal",
                                       "Moves": [
                                         "caca1",
                                         "caca2"
                                       ],
                                       "MovesCount": 2
                                     },
                                     {
                                       "Nature": "loi2",
                                       "EV": "lal",
                                       "Moves": [
                                         "caca1",
                                         "caca2",
                                         "caca3"
                                       ],
                                       "MovesCount": 3
                                     },
                                     {
                                       "Nature": "loi3",
                                       "EV": "lil",
                                       "Moves": [
                                         "caca1",
                                         "caca2",
                                         "caca3"
                                       ],
                                       "MovesCount": 3
                                     }
                                    ]
                                }
                                

                                尝试02//第2部分(运行无痛苦的JMESPath查询以获取所需内容)

                                • 此代码...
                                • Attempt 02 // Part 2 (run the pain-free JMESPath query to get what you want)

                                  • this code ...
                                  • import jmespath
                                    vdata001aa  = """<<json.load(**RE-NORMALIZED** JSON Format Example 1)>>"""
                                    vresult     = jmespath.compile('@|jsontop.nature_table[*].{"Nature":@.Nature,"EV":@.EV,"Moves":@.Moves,"MovesCount":@.MovesCount,"MaxMouvCount":jsontop.settings_info.MaxMouvCount}').search(vdata001aa)
                                    pprint.pprint(vresult)
                                    pass
                                    

                                    • 产生此结果...
                                    • [{'EV': 'lal',
                                        'MaxMouvCount': None,
                                        'Moves': ['caca1', 'caca2'],
                                        'MovesCount': 2,
                                        'Nature': 'loi'},
                                       {'EV': 'lal',
                                        'MaxMouvCount': None,
                                        'Moves': ['caca1', 'caca2', 'caca3'],
                                        'MovesCount': 3,
                                        'Nature': 'loi2'},
                                       {'EV': 'lil',
                                        'MaxMouvCount': None,
                                        'Moves': ['caca1', 'caca2', 'caca3'],
                                        'MovesCount': 3,
                                        'Nature': 'loi3'}]
                                      

                                      • 这不是我们想要的,因为我们在期望的3
                                      • 位置得到了None(又名null)

                                        • this is not what we want, because we get None (aka null) where we expected 3
                                          • 如果JMESPath支持令牌来引用JSON根对象,
                                          • 尝试02 成功
                                          • 一个可行的替代查询是(例如,如果美元符号字符用作对JSON数据根的引用)
                                          • Attempt 02 would have worked, if JMESPath supported a token to refer to the JSON root object
                                          • An alternate query which would work is (if for example, the dollar-sign character worked as a reference to the JSON data root)
                                          import jmespath
                                          vdata001aa  = """<<json.load(**RE-NORMALIZED** JSON Format Example 1)>>"""
                                          vresult     = jmespath.compile('@|jsontop.nature_table[*].{"Nature":@.Nature,"EV":@.EV,"Moves":@.Moves,"MovesCount":@.MovesCount,"MaxMouvCount":$.jsontop.settings_info.MaxMouvCount}').search(vdata001aa)
                                          pprint.pprint(vresult)
                                          pass
                                          

                                          • GitHub上实际上有一个项目解决了JMESPath的这一局限性
                                            • https://github.com/grofers/go-codon/wiki/Jmespath-extensions#3-added--to-refer-to-root-node
                                              • There is actually a project on GitHub that addresses this limitation of JMESPath
                                                • https://github.com/grofers/go-codon/wiki/Jmespath-extensions#3-added--to-refer-to-root-node
                                                  • 尝试01和尝试02表明当前(稳定)的JMESPath版本不能完全满足要求
                                                  • 您将必须突破JMESPath才能从JSON获取所需的动态值并填充重新格式化的数据
                                                  • 或者,您将不得不向JMESPath本身添加一个扩展,这可能比使用托管语言的功能更不受欢迎

                                                  这篇关于如何在多个对象中插入具有动态值的属性或在多个数组中动态添加元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆