【问题标题】:Matching 2 arrays by ids (user[ user id as a key] to orders[value of orders ids array ])按 id 匹配 2 个数组(用户 [用户 id 作为键] 到订单 [订单 id 数组的值])
【发布时间】:2019-08-31 16:41:21
【问题描述】:

我有一个“用户”数组和一个“订单”数组。 我想列出每个 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为key)到orders(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); 

【问题讨论】:

  • 用户112呢?
  • 您应该知道您使用的那些数字键会转换为字符串。我建议查看Map,因为它是专门为此类数据和这些任务设计的。

标签: javascript arrays ecmascript-6 functional-programming


【解决方案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))

【讨论】:

    【解决方案2】:

    我在这里假设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)));

    【讨论】:

    • 您说得对,先生!我只是不确定您的答案是更有效的答案,还是帖子 cmets 中提到的其他选项(使用 if 语句)。
    • 哦,糟糕,正确的用户 ID 是“用户行”中的用户 ID (user.user_id)
    • 最有效的可能是旧的“for”循环。不过,不是很漂亮。 (要两者兼得,最好在 SQL 方面做,这就是 SQL 生活的东西......)
    【解决方案3】:

    您可以使用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)

    【讨论】:

    • 不完全是“纯粹的功能” - 你的减速器正在改变累加器 (` obj[user_id] = obj[user_id] || []; obj[user_id].push(order_id);` ),而不是返回一个新值(新对象)。
    • 但它并没有在用户对象之后被过滤。
    • @mbojko : 它没有变异,如果它被定义了,它只是重新分配,否则它将分配一个新数组作为值
    • push() 正在变异。
    • @mbojko : 是的,他想将它们组合在一起
    猜你喜欢
    • 1970-01-01
    • 2023-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-16
    • 2018-05-04
    • 1970-01-01
    • 2011-07-20
    相关资源
    最近更新 更多