加入两个对象就像 SQL inner join

Join two objects just like SQL inner join

我有两个对象:

countries = [
    { id: 1, name: 'India', image: 'thumb15.jpg' },
    { id: 2, name: 'Africa', image: 'thumb11.jpg' },
    { id: 3, name: 'Kenya', image: 'thumb10.jpg' }
];

cities = [
    { id: 1, name: 'Ahmedabad', country_id: 1 },
    { id: 2, name: 'Vadodara', country_id: 1 },
    { id: 3, name: 'Cairo', country_id: 2 },
    { id: 4, name: 'Kinshasa', country_id: 2 },
    { id: 5, name: 'Luanda', country_id: 2 },
    { id: 6, name: 'Nairobi', country_id: 3 },
    { id: 7, name: 'Nakuru', country_id: 3 },
    { id: 8, name: 'Mombasa', country_id: 3 },
];

我想合并这两个对象,就像SQLINNER JOIN

比如我想对上面两个对象进行如下操作(查询),

SELECT * from countries INNER JOIN cities ON cities.country_id = countries.id

我的预期输出如下:

expected_result = [
    { id: 1, name: "Ahmedabad", country_id: 1, country_name: "India", country_image: "thumb15.jpg" },
    { id: 2, name: "Vadodara", country_id: 1, country_name: "India", country_image: "thumb15.jpg" },
    { id: 3, name: "Cairo", country_id: 2, country_name: "Africa", country_image: "thumb11.jpg" },
    { id: 4, name: "Kinshasa", country_id: 2, country_name: "Africa", country_image: "thumb11.jpg" },
    { id: 5, name: "Luanda", country_id: 2, country_name: "Africa", country_image: "thumb11.jpg" },
    { id: 6, name: "Nairobi", country_id: 3, country_name: "Kenya", country_image: "thumb10.jpg" },
    { id: 7, name: "Nakuru", country_id: 3, country_name: "Kenya", country_image: "thumb10.jpg" },
    { id: 8, name: "Mombasa", country_id: 3, country_name: "Kenya", country_image: "thumb10.jpg" }
];

提前致谢。

您可以为 countries 的所有项目采用散列 table,其中 id 是键,值是所需格式的新对象。

{
    1: {
        country_name: "India",
        image: "thumb15.jpg"
    },
    2: {
        country_name: "Africa",
        image: "thumb11.jpg"
    },
    3: {
        country_name: "Kenya",
        image: "thumb10.jpg"
    }
}

然后使用原始 key/value 和散列 table 中的新属性映射新对象。

使用的方法,按出现顺序:

var countries = [{ id: 1, name: 'India', image: 'thumb15.jpg' }, { id: 2, name: 'Africa', image: 'thumb11.jpg' }, { id: 3, name: 'Kenya', image: 'thumb10.jpg' }],
    cities = [{ id: 1, name: 'Ahmedabad', country_id: 1 }, { id: 2, name: 'Vadodara', country_id: 1 }, { id: 3, name: 'Cairo', country_id: 2 }, { id: 4, name: 'Kinshasa', country_id: 2 }, { id: 5, name: 'Luanda', country_id: 2 }, { id: 6, name: 'Nairobi', country_id: 3 }, { id: 7, name: 'Nakuru', country_id: 3 }, { id: 8, name: 'Mombasa', country_id: 3 }],
    countriesH = countries.reduce((r, { id, name: country_name, ...o }) =>
        (r[id] = { country_name, ...o }, r), {}),
    result = cities.map(o => ({ ...o, ...countriesH[o.country_id] }));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

可以使用 map 函数和 Map 集合来获取所需的国家/地区:

const uniqueCountries = new Map(countries.map(s => [s.id, s]));
const result = cities.map(s => ({ ...s, 
    country_name: uniqueCountries.get(s.country_id).name }));

一个例子:

let countries = [
    { id: 1, name: 'India', image: 'thumb15.jpg' },
    { id: 2, name: 'Africa', image: 'thumb11.jpg' },
    { id: 3, name: 'Kenya', image: 'thumb10.jpg' }
];

let cities = [
    { id: 1, name: 'Ahmedabad', country_id: 1 },
    { id: 2, name: 'Vadodara', country_id: 1 },
    { id: 3, name: 'Cairo', country_id: 2 },
    { id: 4, name: 'Kinshasa', country_id: 2 },
    { id: 5, name: 'Luanda', country_id: 2 },
    { id: 6, name: 'Nairobi', country_id: 3 },
    { id: 7, name: 'Nakuru', country_id: 3 },
    { id: 8, name: 'Mombasa', country_id: 3 },
];

 const uniqueCountries = new Map(countries.map(s => [s.id, s]));
 const result = cities.map(s => ({ ...s, 
     country_name: uniqueCountries.get(s.country_id).name }));
 console.log(result);

更新:

map 方法 从调用数组创建新数组。此外,您可以为您想要的对象添加新的属性:

let countries = [
    { id: 1, name: 'India', image: 'thumb15.jpg' },
    { id: 2, name: 'Africa', image: 'thumb11.jpg' },
    { id: 3, name: 'Kenya', image: 'thumb10.jpg' }
];

const countriesWithShortCountryNames = countries.map(s=> ({...s, 
   shortName: s.name.substring(0, 3)}))
console.log(countriesWithShortCountryNames)

Map collection:

The Map object holds key-value pairs and remembers the original insertion order of the keys.

我写了 a library(它模拟了 dotnet 的 linq),这让这变得轻而易举:

import { blinq } from "blinq";
//...    
const joinedData = blinq(countries)
  .join(
    cities,
    co => co.id,
    ci => ci.country_id,
    (country, city) => ({ country, city })
  )
  .toArray();

const {
  blinq
} = window.blinq;

const countries = [{
    id: 1,
    name: "India",
    image: "thumb15.jpg"
  },
  {
    id: 2,
    name: "Africa",
    image: "thumb11.jpg"
  },
  {
    id: 3,
    name: "Kenya",
    image: "thumb10.jpg"
  }
];

const cities = [{
    id: 1,
    name: "Ahmedabad",
    country_id: 1
  },
  {
    id: 2,
    name: "Vadodara",
    country_id: 1
  },
  {
    id: 3,
    name: "Cairo",
    country_id: 2
  },
  {
    id: 4,
    name: "Kinshasa",
    country_id: 2
  },
  {
    id: 5,
    name: "Luanda",
    country_id: 2
  },
  {
    id: 6,
    name: "Nairobi",
    country_id: 3
  },
  {
    id: 7,
    name: "Nakuru",
    country_id: 3
  },
  {
    id: 8,
    name: "Mombasa",
    country_id: 3
  }
];

const joinedData = blinq(countries)
  .join(
    cities,
    co => co.id,
    ci => ci.country_id,
    (country, city) => ({
      country,
      city
    })
  )
  .toArray();

console.log(JSON.stringify(joinedData, null, 2))
<script src="https://cdn.jsdelivr.net/npm/blinq"></script>