简体   繁体   English

如何将2个JSON对象中的特定值添加到新的JSON对象中

[英]How to add specific values from 2 JSON objects, to a new JSON object

I have extracted the amount of times a country appears in an object (shown at the bottom). 我已经提取了一个国家出现在一个对象中的次数(显示在底部)。 My problem is i need the geocode informaition to go along with they country names+amount of times the appear, so i can plot the actual result on the actual country on my map. 我的问题是我需要地理编码信息及其国家名称+显示的次数,因此我可以在地图上的实际国家/地区上绘制实际结果。

So from the object below, the resulting object from the mapToProp function would be 因此,从下面的对象中,mapToProp函数产生的对象将是

Germany:3,
United Kingdom: 1

But I need something like below. 但是我需要类似下面的内容。 Because this is the format mapbox seemingly expects geojson objects to be. 因为这是mapbox的格式,所以它似乎期望geojson对象成为。

   {
    "type": "FeatureCollection",
    "features": [
        {
            "type": "Feature",
            "geometry": {
                "type": "Point",
                "coordinates": [
                    -77.034084142948,
                    38.909671288923
                ]
            },
            "properties": {
                "name":'Germany',
                "amount": 3
            }
        },
        {
            "type": "Feature",
            "geometry": {
                "type": "Point",
                "coordinates": [
                    -77.034084142948,
                    38.909671288923
                ]
            },
            "properties": {
                "name":'United Kingdom',
                "amount": 4
            }
        }
    ]
}

Getting the country names+the amount of time they appear 获取国家名称+它们出现的时间

   function mapToProp(data, prop) {
        return data
          .reduce((res, item) => Object
            .assign(res, {
              [item[prop]]: 1 + (res[item[prop]] || 0)
            }), Object.create(null))
        ;
      }

The result returned back from the geocoder (this is what country do some specific titles appear in) 从地址解析器返回的结果(这是在其中显示某些特定标题的国家/地区)

var data = [
  {
    bbox: [
      5.866003, 47.270461, 15.041428, 55.0845576
    ],
    center: [
      10, 51
    ],
    geometry: {
      coordinates:[
        10, 51
      ],
      type: "Point"
    }
  }, {
    id: "country.10743216036480410",
    place_name: "Germany",
    place_type: ["country"],
    properties: {
      short_code: "de",
      wikidata: "Q183"
    },
    relevance: 1,
    text: "Germany",
    type: "Feature"
  }, {
    bbox: [
      5.866003, 47.270461, 15.041428, 55.0845576
    ],
    center: [
      10, 51
    ],
    geometry: {
      type: "Point",
      coordinates:[
        10, 51
      ]
    },
    id: "country.10743216036480410",
    place_name: "Germany",
    place_type: ["country"],
    properties: {
      short_code: "de",
      wikidata: "Q183"
    },
    relevance: 1,
    text: "Germany",
    type: "Feature"
  }, {
    bbox: [
      5.866003, 47.270461, 15.041428, 55.0845576
    ],
    center: [
      10, 51
    ],
    geometry: {
      type: "Point",
      coordinates:[
        10, 51
      ]
    },
    id: "country.10743216036480410",
    place_name: "Germany",
    place_type: ["country"],
    properties: {
      short_code: "de",
      wikidata: "Q183"
    },
    relevance: 1,
    text: "Germany",
    type: "Feature"
  }, {
    bbox: [
      -8.718659, 49.802665, 1.867399, 60.945453
    ],
    center: [
      -2, 54
    ],
    geometry: {
      type: "Point",
      coordinates:[
        10, 51
      ],
    },
    id: "country.8605848117814600",
    place_name: "United Kingdom",
    place_type: ["country"],
    properties: {
      short_code: "gb",
      wikidata: "Q145"
    },
    relevance: 1,
    text: "United Kingdom",
    type: "Feature"
  }
]

EDIT: 编辑:

Based on the update desired result (grouping by type then by place_name ) you could do that 2 ways... 根据更新所需的结果(按type分组,然后按place_name分组),您可以执行以下两种方法...

  1. Quick & dirty (more brittle) 快速又脏(更易碎)

    • since you data array only includes objects with the type === Feature , you could just add that property and return them nested in the features array... 由于您的data数组仅包含=== Feature type对象,因此您只需添加该属性并将其嵌套在features数组中即可返回...


function groupByProp(data, prop) {
    let objsByPlaceName = data.reduce((res, item) => {
            if (!item[prop]) 
                return res;
            let existing = res[item[prop]],
                amount = existing && existing.amount
                    ? existing.amount + 1
                    : 1,
                newObj = (() => {
                    if (existing && existing.geometry) 
                        return {amount, geometry: existing.geometry};
                    if (item.geometry) 
                        return {amount, geometry: item.geometry};
                    return {amount};
                })();
            return Object.assign(res, {
                [item[prop]]: newObj
            })
        }, {})

    return {
        "type": "FeatureCollection",
        "features": Object.keys(objsByPlaceName).map(key=> {
             let obj = objsByPlaceName[key];
             return {
                type: "Feature",
                geometry: obj.geometry,
                properties: {
                  name: key,
                  amount: obj.amount
                }
             }
        })
    }
}

There are more efficient way to handle this (N1 vs N^2), but that would require a lot of juggling of property names and manipulating deeply nested values. 有更有效的方法来处理此问题(N1 vs N ^ 2),但这将需要大量处理属性名称和操纵深度嵌套的值。 I'd recommend leaving the initial groupByProp() logic and then flattening that data into the desired structure afterwards. 我建议您保留初始的groupByProp()逻辑,然后将数据展平为所需的结构。

  1. More flexible 更灵活
    • If you're expecting to group elements with different values for type then you will have to group by that property first. 如果期望将type不同的元素分组,则必须首先按该属性分组。 This actually takes quite a bit of work given the data structures so let me know if you actually want the solution before put it together. 给定数据结构,这实际上需要花费大量的工作,因此让我知道您是否真的需要解决方案,然后再将其组合在一起。


INITAL ANSWER: 初始答案:

function groupByProp(data, prop) {
  return data
    .reduce((res, item) => {
      if (!item[prop]) return res;
      let existing = res[item[prop]],
          amount = existing && existing.amount ? existing.amount + 1 : 1,
          newObj = (()=> {
            if (existing && existing.geometry) return {amount, geometry: existing.geometry};
            if (item.geometry) return {amount, geometry: item.geometry};
            return {amount};
          })();
      return Object.assign(res, { [item[prop]]: newObj } )
    },{});
}

groupByProp(data, 'place_name')

This is likely close to what you're looking for except the first element in the data array you provided doesn't have a place_name property so if you wont to hanlde that differently you will have to change this line... 除了您提供的data数组中的第一个元素没有place_name属性外,这可能与您要查找的内容很接近,因此,如果您不想以其他方式处理,则必须更改此行...

if (!item[prop]) return res;

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

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