簡體   English   中英

JavaScript:兩個數組的類似 SQL 的連接

[英]JavaScript: SQL-like join of two arrays

我有這樣的數組:

const one = [
  {id: 1, field1: "a"},
  {id: 2, field1: "b"},
  {id: 3, field1: "c"},
  {id: 4, field1: "d"}
]

const two = [
  {id: 4, field2: "4"},
  {id: 1, field2: "1"}
]
// what I want to achieve:
const result = [
  {id: 1, field1: "a", field2: "1"},
  {id: 4, field1: "d", field2: "4"}
]

我想合並一和二,所以我得到了結果。 這與 SQL 連接非常相似,但我想在 JavaScript 代碼中完成所有這些。 注意:

  1. 這是通過id “列”“加入”。
  2. 結果的順序就是one數組的順序(按ID排序只是巧合順序一樣)
  3. 結果中存在來自兩個數組的字段

我已經想出了如何自己做到這一點,但代碼笨拙且難以閱讀。 基本上,您過濾one並刪除two不存在的元素,然后您映射one並合並two數組的字段。

有沒有更簡潔的方法來實現這一目標? 我正在使用 lodash,我希望有一個功能可以讓這更容易,但我還沒有找到任何功能。

通過鍵( id )創建第二個數組的字典或映射,然后過濾第一個數組,只保留字典中出現的項目。 之后,映射剩余的項目,並添加字典中的相關項目。

 const joinBy = (arr1, arr2, key) => { const arr2Dict = _.keyBy(arr2, key) return arr1 .filter(item => item[key] in arr2Dict) .map(item => ({ ...item, ...arr2Dict[item[key]] })) } const one = [{id: 1, field1: "a"},{id: 2, field1: "b"},{id: 3, field1: "c"},{id: 4, field1: "d"}] const two = [{id: 4, field2: "4"},{id: 1, field2: "1"}]; const result = joinBy(one, two, 'id') console.log(result)
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js" integrity="sha512-90vH1Z83AJY9DmlWa8WkjkV79yfS2n2Oxhsi2dZbIv0nC4E6m5AbH8Nh156kkM7JePmqD6tcZsfad1ueoaovww==" crossorigin="anonymous"></script>

如果您不想使用 lodash,您可以輕松替換_.keyBy() ,並使用Array.reduce()創建一個對象或使用Array.map()創建一個 Map 。

 const joinBy = (arr1, arr2, key) => { const arr2Dict = new Map(arr2.map(o => [o[key], o])) return arr1 .filter(item => arr2Dict.has(item[key])) .map(item => ({ ...item, ...arr2Dict.get(item[key]) })) } const one = [{id: 1, field1: "a"},{id: 2, field1: "b"},{id: 3, field1: "c"},{id: 4, field1: "d"}] const two = [{id: 4, field2: "4"},{id: 1, field2: "1"}]; const result = joinBy(one, two, 'id') console.log(result)
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js" integrity="sha512-90vH1Z83AJY9DmlWa8WkjkV79yfS2n2Oxhsi2dZbIv0nC4E6m5AbH8Nh156kkM7JePmqD6tcZsfad1ueoaovww==" crossorigin="anonymous"></script>

您可以使用lodash mergemapfind函數。 用於排序 - sortBy

_.sortBy(
   _.map(two, (n) => _.merge(n, _.find(one, ['id', n.id]))),
   (o) => _.findIndex(one, ['id', o.id]),
);

 const one = [{id: 1, field1: "a"},{id: 2, field1: "b"},{id: 3, field1: "c"},{id: 4, field1: "d"}], two = [{id: 4, field2: "4"},{id: 1, field2: "1"}]; const r = _.sortBy( _.map(two, (n) => _.merge(n, _.find(one, ['id', n.id]))), (o) => _.findIndex(one, ['id', o.id]), ); console.log(r);
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js"></script>

如果您有不同的字段,您可以獲取一個引用項目的對象並映射two並按id排序。

 const one = [{ id: 1, field1: "a" }, { id: 2, field1: "b" }, { id: 3, field1: "c" }, { id: 4, field1: "d" }], two = [{ id: 4, field2: "4" }, { id: 1, field2: "1" }], fromOne = Object.fromEntries(one.map((object, index) => [object.id, { object, index }])), result = two .map(o => ({ ...fromOne[o.field2].object, ...o })) .sort((a, b) => fromOne[a.field2].index - fromOne[b.field2].index); console.log(result);
 .as-console-wrapper { max-height: 100% !important; top: 0; }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM