Как добавить конкретные значения из 2 объектов JSON в новый объект JSON - PullRequest
0 голосов
/ 27 февраля 2019

Я извлек количество раз, когда страна появляется в объекте (показано внизу).Моя проблема в том, что мне нужно, чтобы информация о геокоде соответствовала названиям стран + количество раз, которое они появляются, чтобы я мог отобразить фактический результат по фактической стране на моей карте.

Итак, из объекта нижерезультирующий объект из функции mapToProp будет

Germany:3,
United Kingdom: 1

Но мне нужно что-то вроде ниже.Поскольку этот формат 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
            }
        }
    ]
}

Получение названий стран + время их появления

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

Результат, возвращаемый из геокодера (это та страна, в которой появляются некоторые конкретные названия)

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"
  }
]

1 Ответ

0 голосов
/ 27 февраля 2019

РЕДАКТИРОВАТЬ:

На основе желаемого результата обновления (группировка по type, затем по place_name), вы можете сделать это двумя способами ...

  1. Быстрый и грязный (более хрупкий)

    • , поскольку в массив data входят только объекты с type === Feature, выможно просто добавить это свойство и вернуть его, вложенный в массив 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
                }
             }
        })
    }
}

Естьболее эффективный способ справиться с этим (N1 против N ^ 2), но это потребовало бы много манипулирования именами свойств и манипулирования глубоко вложенными значениями.Я бы рекомендовал оставить исходную логику groupByProp(), а затем сгладить эти данные в нужную структуру.

Более гибкий
  • Если вы планируете группировать элементы с различными значениями для type, то сначала вам нужно сгруппировать по этому свойству.Это на самом деле требует довольно много работы, учитывая структуры данных, поэтому дайте мне знать, если вы действительно хотите решение, прежде чем собрать его вместе.


INITAL ОТВЕТ:

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')

Это, вероятно, близко к тому, что вы ищете, за исключением того, что первый элемент в предоставленном вами массиве data не имеет place_nameсвойство, так что если вы хотите изменить это по-другому, вам придется изменить эту строку ...

if (!item[prop]) return res;

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...