按ID匹配2个数组(用户[用户ID作为键]匹配订单[订单ID数组的值])

时间:2019-04-10 09:14:06

标签: javascript arrays ecmascript-6 functional-programming

我有一个“用户”数组和一个“订单”数组。 我想列出每个user_id的所有order_id。

var users = {
    0: {
        user_id: 111,
        user_name: "user111",
        isActive: 0
    },
    1: {
        user_id: 112,
        user_name: "use112",
        isActive: 1
    },
    2: {
        user_id: 113,
        user_name: "use113",
        isActive: 0
    },
    ...
}; 

var orders = {  
    888: {
        order_id: 888, 
        user_id: 111
    }, 
    889: {
        order_id: 889, 
        user_id: 111
    }, 
    890: {
        order_id: 890, 
        user_id: 113
    }
};

让我获得以下结果的最佳实践(就效率而言)是什么? 订单的user_ids(以user_id为键)(orders ids数组的值):

result = {
    111: [ 888, 889 ],
    113: [ 890 ]
};

必须使用“用户”对象/数组,因为我的用户变量是已过滤的用户列表,并且userToOrder数组应获取某些特定用户的所有order_id并从中创建一个新对象。

  • 没有for循环,只有纯es6功能。
  • 除非有可能,否则请尽量避免使用.forEach()
  • 除非有“ vanilla es6”示例,否则
  • 没有loadash答案。

这些是我最后的尝试,没有成功:

let userToOrdersArray = users.map( function(user) {

    /*Object.values(orders).reduce((newObj, orderData) => {
        newObj[user.user_id][] = orderData.order_id;
    }, {});*/

    Object.values(orders).filter(function(orderData) {
        return (orderData.user_id === user.user_id); 
    });

});

console.log(userToOrdersArray); 

3 个答案:

答案 0 :(得分:1)

这应该可以解决问题

const users = {
    0: {
        user_id: 111,
        user_name: "user111",
        isActive: 0
    },
    1: {
        user_id: 112,
        user_name: "use112",
        isActive: 1
    },
    2: {
        user_id: 113,
        user_name: "use113",
        isActive: 0
    },
}

  
const orders = {  
  888: {
    order_id: 888, 
    user_id: 111
  }, 
  889: {
    order_id: 889, 
    user_id: 111
  }, 
  890: {
    order_id: 890, 
    user_id: 113
  }
}

const getOrderIdsFromUserId = (user_id, orders) =>
  Object.values(orders).reduce(
    (order_ids, order) => 
      order.user_id===user_id ? [order.order_id,...order_ids] : order_ids,
    []
  )

const f = (users, orders) =>
  Object.values(users).reduce(
    (y, user) => ({
      ...y,
      [user.user_id]: getOrderIdsFromUserId(user.user_id, orders),
    }),
    {},
  )

console.log(f(users, orders))

答案 1 :(得分:0)

您可以使用Array#reduce方法。

var users = {
  111: {
    user_id: 111,
    user_name: "user111",
    isActive: 0
  },
  112: {
    user_id: 112,
    user_name: "use112",
    isActive: 1
  },
  113: {
    user_id: 113,
    user_name: "use113",
    isActive: 0
  },
};
var orders = {
  888: {
    order_id: 888,
    user_id: 111
  },
  889: {
    order_id: 889,
    user_id: 111
  },
  890: {
    order_id: 890,
    user_id: 113
  }
};


// get all property values
var res = Object.values(orders)
  // iterate over values
  .reduce(function(obj, { user_id, order_id }) { // extract  properios using Destructuring feature
    // check user id present in users array
    if (user_id in users) {
      // define array for ids if not defined previously
      obj[user_id] = obj[user_id] || [];
      // push value to array
      obj[user_id].push(order_id);
    }
    // return object
    return obj;
    // set initial value as object
  }, {})

console.log(res)

答案 2 :(得分:0)

我在这里假设对于users对象,密钥始终等于user_id属性。

const users = {
  111: {
    user_id: 111,
    user_name: "user111",
    isActive: 0
  },
  112: {
    user_id: 112,
    user_name: "use112",
    isActive: 1
  },
  113: {
    user_id: 113,
    user_name: "use113",
    isActive: 0
  },
};

const orders = {
  888: {
    order_id: 888,
    user_id: 111
  },
  889: {
    order_id: 889,
    user_id: 111
  },
  890: {
    order_id: 890,
    user_id: 113
  }
};

const groupOrdersByUsers = (usersArr, ordersArr) => usersArr.map(id => ({[id]: ordersArr.filter(({user_id}) => user_id == id)}));

console.log(groupOrdersByUsers(Object.keys(users), Object.values(orders)));