从具有特定 id 的对象的数组生成新数组

Generate new arrays from array with objects with specific id's

我们在项目中使用 ramda,我确实有这个数据结构,我需要做以下事情:

对于每个集合,检查 submittedCheckboxes 是否在其中并将它们隔离到新数组中,这样我就可以知道是否没有超过 valid_amount 设置为 true 的复选框数量.

在下面的示例中,它应该抛出错误指示集合 #1 的 ID,因为 submittedCheckboxes 中的两个具有 value: true,其中集合指定 valid_amount: [1],但集合 #2 应该是很好,因为 valid_amount 选项是 1 或 2,(valid_amount: [1,2])。 最后一组应该接受属于它的所有选中的复选框。

const sets = [
  {id: 1, checkboxes: [{id: 10}, {id: 20}], valid_amount: [1]},
  {id: 2, checkboxes: [{id: 30}, {id: 40}], valid_amount: [1,2]},
  {id: 3, checkboxes: [{id: 50}, {id: 60}, {id: 70}, {id: 80}], valid_amount: [1,2,3,4]},
];

const submittedCheckboxes = [
  {id: 10, value: true},
  {id: 20, value: true},
  {id: 30, value: true},
  {id: 40, value: true},
  {id: 50, value: true},
  {id: 60, value: false},
  {id: 70, value: true},
  {id: 80, value: false},
];

const sets = [
 {id: 1, checkboxes: [{id: 10}, {id: 20}], valid_amount: [1]},
 {id: 2, checkboxes: [{id: 30}, {id: 40}], valid_amount: [1,2]},
 {id: 3, checkboxes: [{id: 50}, {id: 60}, {id: 70}, {id: 80}], valid_amount: [1,2,3,4]},
];

const submittedCheckboxes = [
 {id: 10, value: true},
 {id: 20, value: true},
 {id: 30, value: true},
 {id: 40, value: true},
 {id: 50, value: true},
 {id: 60, value: false},
 {id: 70, value: true},
 {id: 80, value: false},
];
console.log(sets.map(valid));

function valid(set) {
 return set.valid_amount.includes(set.checkboxes.filter(checkbox => submittedCheckboxes.find(set=>set.id === checkbox.id).value).length)
}

我认为首先重新处理您的数据是有意义的:

设置

  1. checkboxes 不需要是对象列表(例如 [{id:1},{id:2}])。它可以只是一个 ID 列表(例如 [1,2]
  2. 我不确定列出所有接受的金额有多大意义。只需指定每个金额可以有的最大值

所以变换:

{id: 2, checkboxes: [{id: 30}, {id: 40}], valid_amount: [1,2]},

进入:

{id: 2, checkboxes: [30, 40], max_amount: 2}

这是一个函数:

const transformSet = set => ({
  id: set.id,
  checkboxes: map(prop('id'), set.checkboxes),
  max_amount: last(set.valid_amount)
});

复选框

似乎(如果我错了请纠正我)您只关心 value 设置为 true 的对象。在这种情况下,我会删除那些 value 设置为 false 的那些,只保留 ID。

所以变换

[
  {id: 10, value: true},
  {id: 20, value: true},
  {id: 30, value: true},
  {id: 40, value: true},
  {id: 50, value: true},
  {id: 60, value: false},
  {id: 70, value: true},
  {id: 80, value: false},
]

进入:

[10, 20, 30, 40, 50, 70]

这是一个函数:

const transformCheckboxes = into([], compose(
  reject(propEq('value', false)),
  map(prop('id'))
));

为什么?

让我们以第 1 组为例,查找答案是否已提交可以像查找两个数组的交集一样简单:

交点([10, 20], [10, 20, 30, 40, 50, 70]) //=> [10, 20]

那么你需要确保数组的长度不大于该集合的最大长度:

const selectCheckboxes = curry((checkboxes, set) =>
  pipe(intersection, length, gte(set.max_amount))
   (set.checkboxes, checkboxes));

现在您可以迭代您的集合,并且您 return 第一个 selectCheckboxes 不 return 的集合。 (注意使用 complement(selectCheckboxes):

const findError = useWith(find, [
  compose(complement(selectCheckboxes), transformCheckboxes),
  map(transformSet)]);

const {curry, into, intersection, length, gte, map, prop, reject, last, useWith, find, compose, propEq, complement, pipe} = R;

const sets = [
  {id: 1, checkboxes: [{id: 10}, {id: 20}], valid_amount: [1]},
  {id: 2, checkboxes: [{id: 30}, {id: 40}], valid_amount: [1,2]},
  {id: 3, checkboxes: [{id: 50}, {id: 60}, {id: 70}, {id: 80}], valid_amount: [1,2,3,4]},
];

const submittedCheckboxes = [
  {id: 10, value: true},
  {id: 20, value: true},
  {id: 30, value: true},
  {id: 40, value: true},
  {id: 50, value: true},
  {id: 60, value: false},
  {id: 70, value: true},
  {id: 80, value: false},
];

const transformSet = set => ({
  id: set.id,
  checkboxes: map(prop('id'), set.checkboxes),
  max_amount: last(set.valid_amount)
});

const transformCheckboxes = into([], compose(
  reject(propEq('value', false)),
  map(prop('id'))
));


const selectCheckboxes = curry((checkboxes, set) =>
  pipe(intersection, length, gte(set.max_amount))
   (set.checkboxes, checkboxes));


const findError = useWith(find, [
  compose(complement(selectCheckboxes), transformCheckboxes),
  map(transformSet)]);

console.log(

  findError(submittedCheckboxes, sets)
  
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.min.js"></script>