简体   繁体   English

如何合并 object 的两个数组

[英]How to merge two array of object

在此处输入图像描述

array1 =数组1 =

[
  {
    "name": {
      "common": "Afghanistan",
      "official": "Islamic Republic of Afghanistan",
    "capital": [
      "Kabul"
    ]
  }
]

array2 =数组2 =

[
"capital": [
          "Kabul"
        ],
"population": 2837743
]

I want to make it我想成功

 [
 {
    "name": {
      "common": "Afghanistan",
      "official": "Islamic Republic of Afghanistan",
    "capital": [
      "Kabul"
    ],
    "population": 2837743
  }
]

I want to merge to an array of objects and make one array.i was try to make it with filter method and find method but can't not solve the problem我想合并到一组对象并创建一个数组。我尝试使用过滤方法和查找方法来制作它,但无法解决问题

There are a few issues with trying to do this because you will need a way of handling the merge from a semantic perspective.尝试执行此操作存在一些问题,因为您需要一种从语义角度处理合并的方法。 You need to choose what fields the merge will match on.您需要选择合并将匹配的字段。 For example, if two countries have the same population you don't want them to be matched and then merged.例如,如果两个国家有相同的人口,您不希望它们被匹配然后合并。

You also need to be aware of and plan for the occurrence of more than two items matching.您还需要注意并计划两个以上项目匹配的发生。 One problem that immediately comes to mind is if the two objects match yet have conflicting information.立即想到的一个问题是这两个对象是否匹配但具有冲突的信息。 This could happen even if they genuinely are a match.即使他们真的是一对,这种情况也可能发生。 Populations change over time.人口随时间而变化。 Even things as rigid as the capital changes.甚至像资本变化一样僵化的事情。

Algorithmically there are two approaches to the matching that I will suggest.在算法上,我将建议两种匹配方法。 The simpler of the two is to have a list of possible fields you want to match the objects on.两者中较简单的是有一个您想要匹配对象的可能字段列表。 You can then create an array (Dictionary or hashmap in other languages) that you key by the value seen so far.然后,您可以创建一个数组(字典或其他语言中的 hashmap),您可以按目前看到的值作为键。

var capital_map = []
for(country in countries1 + countries2){
 if (capital_map[country.capital]){
   //We have a match that we can then handle
 }else{
  //set up for possible matches down the array
  capital_map[country.capital] = country
}

In the above example, we are only matching on the capital.在上面的例子中,我们只匹配大写字母。 You could expand this such that if any one of many fields is matched then we merge the two elements or that at least n of N fields match.您可以扩展它,以便如果许多字段中的任何一个匹配,那么我们合并这两个元素或至少 n 个字段匹配。

The other way I was going to suggest is to create a function that defines some weighted matching.我要建议的另一种方法是创建一个定义一些加权匹配的 function。 For example, what fraction of the fields that overlap are the same, with each field weighted based on the importance, so the population would be of low importance but capital might be of high importance.例如,重叠的字段中有多少部分是相同的,每个字段都根据重要性进行加权,因此人口的重要性可能较低,但资本的重要性可能较高。

I don't know if you want to go deeper in the nesting of the matching of the two arrays, for example with name vs an official name, but I hope you at least have a better idea of the sorts of techniques you could use for that.我不知道您是否想在两个 arrays 的匹配的嵌套中更深入 go,例如名称与官方名称,但我希望您至少对可以使用的各种技术有更好的了解那。 You might have had the array of capitals because you expect issues with entities that pass matching but have overlapping fields and didn't want to worry about a resolution.您可能拥有大写字母数组,因为您期望通过匹配但具有重叠字段并且不想担心解决方案的实体会出现问题。 (Such as just taking the average for the population) If you do intend to expand this to more than two sources of data, more than two arrays you can do things like have voting where each source votes for its answer. (例如只取人口的平均值)如果您确实打算将其扩展到两个以上的数据源,超过两个 arrays,您可以执行投票等操作,每个来源对其答案进行投票。 If two sources say the capital is Brazilia and only one of the three says Rio then you can go with Brazilia.如果两个消息来源说首都是巴西利亚,而三个消息来源中只有一个说里约,那么您可以 go 与巴西利亚。

You can do something like this (I left capital as an array, but it would be simpler if it were not):你可以做这样的事情(我把capital作为一个数组,但如果不是这样会更简单):

const arr1 = [
  {
    name: {
      common: 'Afghanistan',
      official: 'Islamic Republic of Afghanistan',
    },
    capital: ['Kabul'],
  },
  {
    name: {
      common: 'Albania',
      official: 'Republic of Albania',
    },
    capital: ['Tirana'],
  },
];

const arr2 = [
  { capital: ['Tirana'], population: 2845955 },
  { capital: ['Kabul'], population: 2837743 },
];

const populationByCapital = new Map();

for (let el of arr2) {
  populationByCapital.set(el.capital[0], el.population);
}

const arr3 = arr1.map((el) => {
  return { ...el, population: populationByCapital.get(el.capital[0]) };
});

console.log(arr3);

this should give you:这应该给你:

[
  {
    name: {
      common: 'Afghanistan',
      official: 'Islamic Republic of Afghanistan'
    },
    capital: [ 'Kabul' ],
    population: 2837743
  },
  {
    name: { common: 'Albania', official: 'Republic of Albania' },
    capital: [ 'Tirana' ],
    population: 2845955
  }
]

Note that it might break if there are two countries with the same capital names.请注意,如果有两个国家的首都名称相同,它可能会中断。


Edit编辑

I see now that you were using the API from restcountries.com , thus changing capital to a scalar is beyound your control.我现在看到您正在使用来自 restcountries.com 的API ,因此将capital更改为标量是您无法控制的。 And there's a reason why it's an array -- South Africa has 3 capitals.它是一个数组是有原因的——南非有 3 个首都。 The code should still work because it's the same API, and all 3 are listed in the same order in both endpoints.该代码应该仍然有效,因为它是相同的 API,并且所有 3 个在两个端点中都以相同的顺序列出。

But there are couple of complications.但是有几个并发症。 The country of Bouvet Island has apparently no capital, and so the array will be empty, and the country of Norfolk Island, and Jamaica have both "Kingston" as the capital.布维岛国显然没有首都,所以阵列将是空的,诺福克岛国和牙买加都以“金斯敦”为首都。 To address both of these issues you can change the key to include the name of the country together with the capital:要解决这两个问题,您可以更改键以包含国家名称和首都:

const populationByCapital = new Map();

for (let el of arr2) {
  populationByCapital.set(el.capital[0] + el.name.common, el.population);
}

const arr3 = arr1.map((el) => {
  return {
    ...el,
    population: populationByCapital.get(el.capital[0] + el.name.common),
  };
});

I modified your starting data to fix some syntax errors:我修改了您的起始数据以修复一些语法错误:

const array1 = [
    {
        name: {
            common: 'Afghanistan',
            official: 'Islamic Republic of Afghanistan',
        },
        capital: ['Kabul'],
    },
];

const array2 = [
    {
        capital: ['Kabul'],
        population: 2837743,
    },
];

As requested, this merge uses the filter method to match the two objects:根据要求,此合并使用 filter 方法来匹配两个对象:

const newArray = array1.map((arr1Obj) => {
    const capitalObj = array2.filter(
        (arr2Obj) =>
            JSON.stringify(arr1Obj.capital) === JSON.stringify(arr2Obj.capital)
    );

    return Object.assign(arr1Obj, ...capitalObj);
});

console.log(newArray);

Output: Output:

[
    {
        name: {
        common: 'Afghanistan',
        official: 'Islamic Republic of Afghanistan',
        },
        capital: ['Kabul'],
        population: 2837743,
    },
];

First process the data of array2 and build any object with key as capitol and value as object.首先处理array2的数据,构建任意object,key为capitol,value为object。 Use map and array1 and add the corresponding capitol info from process data (track2)使用map和 array1 并从过程数据 (track2) 添加相应的首都信息

 const array1 = [ { name: { common: "Afghanistan", official: "Islamic Republic of Afghanistan", }, capital: ["Kabul"], }, ]; const array2 = [ { capital: ["Kabul"], population: 2837743, }, ]; const track2 = {}; array2.forEach(({ capital: [city], ...rest }) => (track2[city] = rest)); const result = array1.map((item) => ({...item, ...track2[item.capital?.[0]], })); console.log(result)

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

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