簡體   English   中英

Javascript:使用一個鍵對對象數組進行完全外連接

[英]Javascript: Full Outer Join on a Array of Objects, using one key

我有兩個對象數組,我想“完全外連接”,就像在 SQL 中一樣:

數據集 A:

[ { id: 1, name: "apple", color: "red" }, {id: 2, name: "banana", color: "yellow"} ]

數據集 B:

[ { id: 1, name: "apple", color: "blue" }, {id: 3, name: "mango", color: "green"} ]

預期結果:

[ { id: 1, dataset_a: { id: 1, name: "apple", color: "red" }
         , dataset_b: { id: 1, name: "apple", color: "blue" }
  }
, { id: 2, dataset_a: { id: 2, name: "banana", color: "yellow"}
         , dataset_b: null
  }
, { id: 3, dataset_a: null
         , dataset_b: { id: 3, name: "mango", color: "green"}
  }
]
  • id 是唯一的。
  • 可以使用 Lodash。
  • 我對 ES 版本沒有限制。

而不是 null,一個空對象也可以。 id不一定要重復,如下圖。 所以,這同樣好:

[ { id: 1, dataset_a: { name: "apple", color: "red" }
         , dataset_b: { name: "apple", color: "blue" }
  }
, { id: 2, dataset_a: { name: "banana", color: "yellow"}
         , dataset_b: {}
  }
, { id: 3, dataset_a: {}
         , dataset_b: { name: "mango", color: "green"}
  }
]

Nina Scholtz 解,轉化為 aa 函數:

fullOuterJoin(dataset_a_name, dataset_b_name, dataset_a, dataset_b, key) {
    const getNullProperties = keys => Object.fromEntries(keys.map(k => [k, null]));
    var data = { [dataset_a_name]:dataset_a, [dataset_b_name]:dataset_b },
        result = Object
            .entries(data)
            .reduce((r, [table, rows]) => {
                //forEach dynamic destructuring
                rows.forEach(({ [key]:id, ...row }) => {
                    if (!r[id]) r.items.push(r[id] = { [key]:id, ...getNullProperties(r.tables) });
                    r[id][table] = row;
                });
                r.tables.push(table);
                r.items.forEach(item => r.tables.forEach(t => item[t] = item[t] || null));
                return r;
            }, { tables: [], items: [] })
            .items;

    return result;
},

專門滿足您需求的代碼片段:

const datasetA = [ { id: 1, name: "apple", color: "red" }, {id: 2, name: "banana", color: "yellow"} ]
const datasetB = [ { id: 1, name: "apple", color: "blue" }, {id: 3, name: "mango", color: "green"} ]


const joined = [];

// datasetA
for (let i = 0; i < datasetA.length; i++) {
    let item = {
        id: datasetA[i].id,
        dataset_a: datasetA[i],
    };
    joined.push(item);
}
// datasetB
for (let i = 0; i < datasetB.length; i++) {
    const foundObject = joined.find(d => d.id === datasetB[i].id);
    if (foundObject) {
        foundObject['dataset_b'] = datasetB[i];
    }
    else {
        let item = {
            id: datasetB[i].id,
            dataset_a: {},
            dataset_b: datasetB[i],
        };
        joined.push(item);
    }
}

console.log(joined);

您可以采用動態方法並將所需的數據集存儲在對象中,然后從對象中迭代條目。 然后按id分組並取回所有項目。

這種方法使用對象作為哈希表,以id作為鍵,使用數組作為結果集的存儲。 如果id未知,則使用具有id的新對象和先前使用的具有null值的鍵。 然后將實際數據集添加到對象中。

最后,對於缺少的表, null值也被分配。

 const getNullProperties = keys => Object.fromEntries(keys.map(k => [k, null])); var dataset_a = [{ id: 1, name: "apple", color: "red" }, { id: 2, name: "banana", color: "yellow" }], dataset_b = [{ id: 1, name: "apple", color: "blue" }, { id: 3, name: "mango", color: "green" }], data = { dataset_a, dataset_b }, result = Object .entries(data) .reduce((r, [table, rows]) => { rows.forEach(({ id, ...row }) => { if (!r[id]) r.items.push(r[id] = { id, ...getNullProperties(r.tables) }); r[id][table] = row; }); r.tables.push(table); r.items.forEach(item => r.tables.forEach(t => item[t] = item[t] || null)); return r; }, { tables: [], items: [] }) .items; console.log(result);
 .as-console-wrapper { max-height: 100% !important; top: 0; }

var array1 = [ { id: 1, name: "apple", color: "red" }, {id: 2, name: "banana", color: "yellow"} ]
var array2 = [ { id: 1, name: "apple", color: "blue" }, {id: 3, name: "mango", color: "green"} ]

var array_sum = array1.concat(array2)

var array_result = []

array_sum.forEach(function(candidate, index){
  var obj_id = candidate.id;
  delete candidate.id
  if(array_result.length == 0){
    array_result.push({
      "id": obj_id,
      ["dataset_" + index]: candidate
    })
  }else{
    for(var i=0; i<array_result.length; i++){
      if(array_result[i].id == obj_id){
        array_result[i]["dataset_" + index] = candidate
        break;
      }else if(i == array_result.length - 1){
        array_result.push({
          "id": obj_id,
          ["dataset_" + index]: candidate
        })
      }
    }
  }
})
console.log(array_result)

暫無
暫無

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

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