How can I perform an inner join with two object arrays in JavaScript?

后端 未结 7 1982
闹比i
闹比i 2020-12-10 13:56

I have two object arrays:

var a = [
  {id: 4, name: \'Greg\'},
  {id: 1, name: \'David\'},
  {id: 2, name: \'John\'},
  {id: 3, name: \'Matt\'},
]

var b = [         


        
7条回答
  •  时光取名叫无心
    2020-12-10 14:38

    You do not reduce the problems complexity by moving a search into the native code. The search must still be done.

    Also the addition of the need to null a undefined property is one of the many reasons I dislike using null.

    So without the null the solution would look like

    var a = [
      {id: 4, name: 'Greg',position: '7'},
      {id: 1, name: 'David'},
      {id: 2, name: 'John'},
      {id: 3, name: 'Matt'},
    ]
    
    var b = [
      {id: 5, name: 'Mathew', position: '1'},
      {id: 6, name: 'Gracia', position: '2'},
      {id: 2, name: 'John', position: '2'},
      {id: 3, name: 'Matt', position: '2'},
    ]
    
    
    function join (indexName, ...arrays) {
        const map = new Map();
        arrays.forEach((array) => {
            array.forEach((item) => {
                map.set(
                    item[indexName],
                    Object.assign(item, map.get(item[indexName]))
                );
            })
        })
        return [...map.values()];
    }
    

    And is called with

    const joinedArray = join("id", a, b);
    

    To join with a default is a little more complex but should prove handy as it can join any number of arrays and automatically set missing properties to a provided default.

    Testing for the defaults is done after the join to save a little time.

    function join (indexName, defaults, ...arrays) {
        const map = new Map();
        arrays.forEach((array) => {
            array.forEach((item) => {
                map.set(
                    item[indexName], 
                    Object.assign( 
                        item, 
                        map.get(item[indexName])
                    )
                );
            })
        })
        return [...map.values()].map(item => Object.assign({}, defaults, item));
    
    }
    

    To use

    const joinedArray = join("id", {position : null}, a, b);
    

    You could add...

        arrays.shift().forEach((item) => {  // first array is a special case.
            map.set(item[indexName], item);
        });
    

    ...at the start of the function to save a little time, but I feel it's more elegant without the extra code.

提交回复
热议问题