有没有一种方法可以将值从一个键:值映射复制到另一个?

时间:2020-02-12 18:36:56

标签: javascript json

我正在尝试将一个映射的值复制到另一个映射,一些值存储为字符串,而另一些则存储为数组或列表。
例如:

map 1: {
    "name"        : "target_name",
    "description" : "item_desc",
    "status"      : "status",
    "budget: [ { "timeframe": "", "type": "", "amount":""  } ]
    }"

我编写了一个函数,该函数接收一个映射(如上面的映射)和一个JSON原始结果,并扫描JSON响应以查找匹配的键和值对。
例如,"name": "target_name"
“名称”是地图上的键
"target_name"是JSON中的密钥。

一旦遇到嵌套值,例如:

"budget: [ { "timeframe": "", "type": "", "amount":""  } ]"

我陷入困境,我不知道如何从JSON响应中获取密钥。
此处附上的是我写的代码:

     function oneOffrAppendToData(map,jsonResultRaw) {
        var jsonData = JSON.parse(getTemplate())
        for(var mapkey in map ){
            for(var key in jsonResultRaw){
                if(map[mapkey]==key){
                    for(var jsonKey in jsonData){
                        if(jsonKey==mapkey){
                            jsonData[jsonKey]=jsonResultRaw[key]
                        }
                    }
                    //jsonData.mapkey =jsonResultRaw[key]

                }
            }
        }

1 个答案:

答案 0 :(得分:0)

我强烈建议您不要通过扫描JSON或类似方法来做到这一点。使用对象和递归。

根据我收集的信息,您希望扫描具有可能具有数组值的属性的地图(旧地图)。当找到这些属性之一时,只要其值不是数组,就希望将键/值写入另一个对象(newmap)。如果它是一个数组,则要继续扫描它(递归)。

一个问题是,如果两次找到相同的属性名称并将其写入新对象,它将覆盖旧的属性名称。这是一个可解决的问题,但现在让我着重于您的特定示例。

此代码在“ oldmap”中扫描属性列表,如果找到,则将该键/值写入“ newmap”。

首先,它检查是否已将其喂入数组。如果是这样,它将拉出第一个对象并再次检查。这会重复进行,直到找到不是数组的东西为止(这里我们假设它会找到数组或映射,而没有其他东西)。

找到对象时,它将遍历其键并在找到指示的属性时执行newmap的写操作。如果找到一个数组作为该对象的值之一,它将再次递归。此递归最终到达嵌套的末尾,然后展开回到顶部,从而生成地图。

我写的是这样的,我可以避免使用两个块检查数组,但是我认为现在这是一个很容易理解的示例。

此外,我可以通过输入值列表来扩展它,这样,如果找到键N,则可以使用val N将其写入新对象。尽管如此,这还不属于您的请求。

const oldmap = {
"name":  "target_name",
"description": "item_desc",
"status":"status",
"budget": [
    {
        "timeframe": "",
        "type": "",
        "amount":"" 
    }
  ]
};

const newMap = {};
function createNewMap ( map, keys ) {
    if ( Array.isArray ( map ) && map.length ) {
      createNewMap ( map [ 0 ], keys );
    }
    Object.keys ( map ).forEach ( x => {
      if ( keys.indexOf ( x ) >= 0 ) {
        newMap [ x ] = map [ x ];
      }
      if ( Array.isArray ( map [ x ] ) && map [ x ].length >= 0  ) {
        createNewMap ( map [ x ], keys );
      } 
    });
}

createNewMap ( oldmap, [ 'name', 'type', 'amount' ] );
console.log ( newMap );
// Output: {name: "target_name", type: "", amount: ""}