如何将特定项目组合在同一阵列中的对象中,并将其从核心阵列中删除? [英] How can I group specific items within an object in the same array and delete them from the core array?

查看:40
本文介绍了如何将特定项目组合在同一阵列中的对象中,并将其从核心阵列中删除?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在努力实现一些复杂的事情.

I am trying to achieve something a bit complex.

我正在使用一种分组功能,在该功能中,我必须获取包含 checked:true 键的项目,然后将它们放到名为 questionGroup 的键/数组中>在数组中的第一项中,选中 checked:true ,然后删除其他已分组的项.

I am working on a grouping feature where I have to get the items containing the key checked: true then I need to put them together within the key/array named questionGroup in the first item in the array with checked: true and then deleting the other items that were grouped.

查看数据结构:

const dummyQuestions = [
  {
    id: 1,
    checked: false,
    question: {...},
    questionGroup: []
  },
  {
    id: 2,
    checked: true,
    question: {...},
    questionGroup: []
  },
  {
    id: 3,
    checked: false,
    question: {...},
    questionGroup: []
  },
  {
    id: 4,
    checked: true,
    question: {...},
    questionGroup: []
  },
  {
    id: 5,
    checked: true,
    question: {...},
    questionGroup: []
  }
];

因此,假设您单击某个触发分组功能的按钮,因为您注意到索引 1 3 4 具有选中:true ,因此这必须发生:

So lets say you clicked on a certain button which fires a grouping function, as you noticed index 1, 3 and 4 have checked: true, so this must happen:

const dummyQuestions = [
  {
    id: 1,
    checked: false,
    question: {...},
    questionGroup: []
  },
  {
    id: 2,
    checked: true,
    question: {...},
    questionGroup: [
      {
        id: 2,
        checked: true,
        question: {...},
        questionGroup: []
      },
      {
        id: 4,
        checked: true,
        question: {...},
        questionGroup: []
      },
      {
        id: 5,
        checked: true,
        question: {...},
        questionGroup: []
      }
    ]
  },
  {
    id: 3,
    checked: false,
    question: {...},
    questionGroup: []
  }
];

这就是将数据分组后的样子.

That's how the data must be after grouping it.

你知道这个主意吗?

我创建了可复制的演示=> https://codesandbox.io/s/ts-react-grouping-odxs1?file =/src/App.tsx

I created a reproducible demo => https://codesandbox.io/s/ts-react-grouping-odxs1?file=/src/App.tsx

编辑

这是相关代码:

const handleGroupQuestions = (): void => {
    const questionAddedCopy: VariableConfig[] = [...questionAdded];

    // Only the questions with checked === true will be grouped.
    const filteredCopy: VariableConfig[] = questionAddedCopy.filter(
      (q: VariableConfig) => q.checked === true
    );

    const grouped: VariableConfig[] = [
      ...questionAdded.filter((q: VariableConfig) => filteredCopy.includes(q))
    ];

    for (let i = 0; i < grouped.length; i++) {
      // Here I compare the ids and I put them together into the key questionGroup
      if (filteredCopy[i].id === grouped[i].id) {
        // I had to set any instead of VariableConfig type because otherwise TS throws an error
        addQuestion((q: any) => {
          const questionsCopy = [...q];

          const mergedQuestions: VariableConfig[] = [
            ...questionsCopy,
            { ...grouped[i], questionGroup: grouped }
          ];

          // With this `unique` function what I am trying to achieve (which I am not) is
          // to have a unique ID per every question/item in the array.
          // I need to add the questions to questionGroup to the highest item containing check = true
          // I need to delete from the main array, the items going inside questionGroup.
          const unique = [
            ...mergedQuestions.filter((c) => c.id !== questionsCopy[i].id)
          ];

          return unique;
        });
        break;
      }
    }
  };

并深入解释并回答您的问题.

And to explain more in deep and to answer your questions.

我们看到具有 checked:true 的数组中的第一项是ID为 2 的项,因此这是我必须存储的位置其他已 checked:true 的项目,因为那是数组中的最高项目,那么我需要从数组中删除分组为 questionGroup 的项目.

We see that the first item in the array with checked: true is the item with the id 2, so that will be the place where I have to stored the other items with checked: true because that is the highest item in the array, then I need to delete from the array the items that were grouped into questionGroup.

在这种情况下,重复ID 2 ,这是必需的,因为一个ID是父代的,而 questionGroup 中的另一个是它自己的子代,请获取它?就像是将自身存储在 questionGroup 中一样.

The id 2 in this case is repeated and that is a requirement, because one id is for the parent and the other one within questionGroup is its own child, get it? Like if it is storing itself into questionGroup.

这只是一个分组功能,我在其中保存了一些步骤.想象每个项目都包含一个复选框,因此要分组的项目必须首先进行检查,然后单击 GROUP THEM 按钮,选中的项目消失,然后合并到最高的选中索引中,保留其 id 并保存自身.

This is just a grouping functionality where I am saving some steps. Imagine every item contains a checkbox, so the items that you want to group, you have to check them first, then click the GROUP THEM button, the checked items disappear and then get together into the highest checked index, keeping its id and storing itself as well.

看看我发布的数组.在那里,您可以看到我需要的确切输出.

Take a look at the arrays I posted. There you can see what is the exact output I need.

推荐答案

这是一种技术:

// helper function
const addChecked = (q, qs) =>
  ({...q, questionGroup: qs .filter (p => p .checked)})

// main function
const nestChecked = (qs, found = false) =>
  qs .flatMap (q => q .checked ? found ? [] : (found = true, [addChecked (q, qs)]) : [q])

// sample data
const dummyQuestions = [{id: 1, checked: false, question: 'foo', questionGroup: []}, {id: 2, checked: true, question: 'bar', questionGroup: []}, {id: 3, checked: false, question: 'baz', questionGroup: []}, {id: 4, checked: true, question: 'qux', questionGroup: []}, {id: 5, checked: true, question: 'corge', questionGroup: []}]

// demo
console .log  (JSON .stringify (nestChecked (dummyQuestions), null, 4))

.as-console-wrapper {max-height: 100% !important; top: 0}

我们有一个简单的帮助程序功能,可以将输入中所有选中的元素分组为一个特定问题(的一个副本).

We have a simple helper function that groups all the checked elements of the input into (a copy of) a specific question.

我们的主要功能使用 .flatMap 遍历问题,这使我们可以进行过滤并在一次遍历中进行映射.我们维护一个标志 found ,它告诉我们是否已经处理了选中的元素.对于每个问题,如果未选中,则只需将其包装在数组中,并从 flatMap 回调中以 [q] 的形式返回即可.如果选中,我们将评估 found 标志.如果将其设置为 true ,则我们返回并且为空数组.如果不是,则返回上面调用我们的辅助函数的结果,并再次包装在数组中.(这些数组包装器不是专门为解决此问题而设计的;但我想在 flatMap 回调中返回一致的类型.)

Our main function iterates over the questions with .flatMap, which allows us to do a filter and map in a single traversal. We maintain a flag, found which tells us if we've already handled the checked elements. For each question, if it's not checked, we simply include it, by returning it wrapped in an array, as [q] from the flatMap callback. If it is checked, we evaluate the found flag. If that is set to true, then we return and empty array. If it's not, we return the result of calling our helper function above, again wrapped in an array. (These array wrappers are not specifically needed for this problem; but I like to return a consistent type in the flatMap callback.)

我们可以轻松地内联该辅助函数,因为它仅被调用一次.实际上,这就是我最初编写它的方式.但这让我感觉更干净了.

We could easily inline that helper function, as it's only called once. In fact that's how I originally wrote it. But it feels cleaner to me separated.

我不清楚是否有一些迭代过程可以进一步嵌套这些过程.如果是这样,您可能必须在帮助程序函数中做一些更复杂的事情,以处理已经填充的 questionGroup 字段.但这可能是一个不同的问题.

It's not clear to me if there is some iterative process which will then further nest these. If so, you might have to do something more sophisticated in the helper function dealing wit already-populated questionGroup fields. But that would probably be for a different question.

最后,我们还可能希望避免使用该默认参数.有时候有有充分的理由.我将此更改留给读者练习.:-)

Finally, we also might want to avoid that default parameter. There are sometimes good reasons to want to do so. I leave this change as an exercise for the reader. :-)

这篇关于如何将特定项目组合在同一阵列中的对象中,并将其从核心阵列中删除?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆