简体   繁体   English

jq 1.5:将一个数组中的键与它们在不同数组中的值组合在一起

[英]jq 1.5: Combining keys from one array with their values that are in a different array

I'd like to take some key values that are found in one array, and match them with their corresponding values in a different array. 我想获取一个数组中的一些键值,并将它们与不同数组中的相应值进行匹配。 For reference I'm using jq-1.5 作为参考,我使用的是jq-1.5

I've got some data from the quandl api where I'm pulling some stock data. 我从quandl api获得了一些数据,我正在提取一些股票数据。 For example, the following pulls down some json data. 例如,以下内容会删除一些json数据。

curl https://www.quandl.com/api/v3/datatables/WIKI/PRICES.json?ticker=FB&qopts.columns=date,close,high,low&api_key=myapikeyblahblah curl https://www.quandl.com/api/v3/datatables/WIKI/PRICES.json?ticker=FB&qopts.columns=date,close,high,low&api_key=myapikeyblahblah

The data is as follows, though I've removed some of the redundant data; 数据如下,虽然我删除了一些冗余数据;

{
  "datatable": {
    "data": [
      ["2012-05-18", 38.2318, 45.0, 38.0],
      ["2012-05-21", 34.03, 36.66, 33.0],
      ["2012-05-22", 31.0, 33.59, 30.94],
      ["2017-06-22", 153.4, 154.55, 152.91],
      ["2017-06-23", 155.07, 155.2, 152.65]
    ],
    "columns": [{
      "name": "date",
      "type": "Date"
    }, {
      "name": "close",
      "type": "BigDecimal(34,12)"
    }, {
      "name": "high",
      "type": "BigDecimal(34,12)"
    }, {
      "name": "low",
      "type": "BigDecimal(34,12)"
    }]
  },
  "meta": {
    "next_cursor_id": null
  }
}

I'm looking to match the "keys" from the .datatable.columns[$index1].name with the "values" in .datatable.data[1] and so on with each iterating index value. 我希望将.datatable.columns [$ index1] .name中的“键”与.datatable.data [1]中的“values”匹配,依此类推每个迭代索引值。 I'm looking to get an output like the following; 我希望获得如下输出;

[
  {
    "date": "2012-05-18",
    "close": 38.2318,
    "high": 45.0,
    "low": 38.0
  },
  {
    "date": "2012-05-21",
    "close": 34.03,
    "high": 36.66,
    "low": 33.0
  },
  {
    "date": "2012-05-22",
    "close": 31.0,
    "high": 33.59,
    "low": 30.94
  },
  {
    "date": "2017-06-22",
    "close": 153.4,
    "high": 154.55,
    "low": 152.91
  },
  {
    "date": "2017-06-23",
    "close": 155.07,
    "high": 155.2,
    "low": 152.65
  }
]

So far i've played around with the idea of counting up the index, but most of my solutions so far have been fairly verbose, and i'm finding myself stepping out of jq to sed/awk etc for something that I imagine is easy in jq. 到目前为止,我已经玩弄了计算索引的想法,但到目前为止,我的大部分解决方案都相当冗长,而且我发现自己走出jq到sed / awk等等我想象的很容易在jq。

Here's a helper function to make the solution easy to understand. 这是一个帮助函数,使解决方案易于理解。 It converts the input array into an object, on the assumption that headers is an array of strings to be used as key names: 它将输入数组转换为一个对象,假设headers是一个字符串数组,用作键名:

def objectify(headers):
  [headers, .] | transpose | map( { (.[0]): .[1] } ) | add;

A solution is now straightforward: 解决方案现在很简单:

.datatable
| (.columns | map(.name)) as $headers
| .data
| map( objectify($headers) )

Python solution: Python解决方案:

combine_keys.py script: combine_keys.py脚本:

import sys, json

data = json.load(open(sys.argv[1], 'r'))
columns = [o['name'] for o in data['datatable']['columns']]
result = json.dumps([dict(zip(columns, i)) for i in data['datatable']['data']], indent=4)
print(result)

Usage : 用法

python combine_keys.py input.json

The output: 输出:

[
    {
        "low": 38.0,
        "date": "2012-05-18",
        "close": 38.2318,
        "high": 45.0
    },
    {
        "low": 33.0,
        "date": "2012-05-21",
        "close": 34.03,
        "high": 36.66
    },
    {
        "low": 30.94,
        "date": "2012-05-22",
        "close": 31.0,
        "high": 33.59
    },
    {
        "low": 152.91,
        "date": "2017-06-22",
        "close": 153.4,
        "high": 154.55
    },
    {
        "low": 152.65,
        "date": "2017-06-23",
        "close": 155.07,
        "high": 155.2
    }
]

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

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