在数组内过滤数据并返回使用组

时间:2019-07-08 13:26:48

标签: javascript vue.js vuejs2

我有一个类似的对象,我需要过滤每个组项目中的规则,但是,我还需要返回“ 组名称”过滤规则

{
  "id": "rulesCompany",
  "group": [
    {
      "name": "Cadastral",
      "rule": [
        {
          "title": "Receita Federal",
          "description": "Fonte atualizada mensalmente.",
          "homonym": false,
          "criticality": "high"
        },
        {
          "title": "CNAE Primário - Alteração",
          "description": "Fonte atualizada mensalmente.",
          "homonym": false,
          "criticality": "high"
        },
      ]
    },
    {
      "name": "Dados modelados",
      "rule": [
        {
          "title": "Nível de Atividade - Alteração",
          "description": "Fonte atualizada mensalmente.",
          "homonym": false,
          "criticality": "high"
        },
        {
          "title": "Faturamento Presumido",
          "description": "Fonte atualizada mensalmente.",
          "homonym": false,
          "criticality": "medium"
        }
      ]
    },
  ]
}

enter image description here

例如,如果我在搜索字段中搜索“ Rece”,则需要返回“ Cadastral / Receita Federal”组,但是我不知道如何过滤数据内部的数据。

到目前为止我所做的:

Module.vue

<template>
  <div>
    <slide-out :visible.sync="isVisible" :title="text.header">
      <div slot="header">
        <div>
          <button class="neo-bt-icon--big slideout__close--button" @click="isVisible=false">
            <svg><use xlink:href="/red/neo-assets/images/simple-line-icons.svg#arrow-2-left"></use></svg>
          </button>
          <h1 class="slideout__header--text">
            {{ text.header }}
          </h1>
          <div class="neo-form-toggle-list__item neo-form-toggle neo-form-toggle--checkbox">
            <input type="text" class="neo-form-field" placeholder="Buscar" v-model="searchQuery">
            <input class="neo-form-toggle__field" :id="selectAllRules" @click="selectAllRules($event)" type="checkbox"/>
            <label class="neo-form-toggle__label" :for="selectAllRules">selecionar tudo</label>
          </div>
        </div>
      </div>
      <div slot="content">
        <div v-for="policyRule in filteredPolicyRules.group" :key="policyRule.name"
          class="neo-form-group">
          <li v-text="policyRule.name"></li>
          <div class="neo-form-toggle-list__item neo-form-toggle neo-form-toggle--checkbox">
            <input class="neo-form-toggle__field" :id="policyRule.name" @click="selectGroupRules(policyRule.rule, policyRule.name, $event)" type="checkbox" v-model="policyRules.name" />
            <label class="neo-form-toggle__label" :for="policyRule.name">selecionar grupo</label>
          </div>
          <div class="neo-form-toggle-list neo-form-toggle-list--inline">
            <div v-for="rule in policyRule.rule" :key="rule.title"
              class="neo-form-toggle-list__item neo-form-toggle neo-form-toggle--checkbox">
              <input class="neo-form-toggle__field" :id="rule.title" :value="rule" name="rule" type="checkbox" v-model="checkedRules"/>
              <label class="neo-form-toggle__label" :for="rule.title">{{ rule.title }}</label>
              <h6 class="neo-text-disabled-options">{{ rule.description }}</h6>
            </div>
          </div>
        </div>
      </div>
      <div slot="footer">
        <span>{{ checkedRules  }}</span>
      </div>
    </slide-out>
  </div>
</template>

<script>
import { mapState } from 'vuex';

import SlideOut from '@/components/shared/slideout/SlideOut.vue';

export default {

  name: 'ModulePolicyRules',
  props: [],
  components: {
    SlideOut,
  },
  data() {
    return {
      isVisible: false,
      policyRules: [],
      searchQuery: '',
      checkedRules: [],
      filteredRules: [],
    };
  },
  computed: {
    filteredPolicyRules() {
      const me = this;
      if (this.searchQuery) {
        me.filteredRules.pop();
        this.policyRules.group.filter((ruleGroup) => {
          ruleGroup.rule.forEach((rule) => {
            if (rule.title.startsWith(this.searchQuery)) {
              console.log(me.filteredRules);
              me.filteredRules.push(rule);
            }
          });
        });
        console.log(me.filteredRules);
        return me.filteredRules;
        // return this.policyRules.group.filter(item => item.name.startsWith(this.searchQuery));
      }
      return this.policyRules;
    },
  },
  methods: {
    async loadData() {
      const rules = await this.$store.dispatch('policyrules/setPolicyRules');
      this.policyRules = rules;
    },
  },
  mounted() {
    this.loadData();
  },
};
</script>

<style lang="scss">
  .neo-form-toggle__label {
    text-transform: none;
    font-weight: 600;
  }

  .neo-text-disabled-options {
    text-transform: none;
  }
</style>
在搜索字段中使用“ Rec”

对象预期结果

{
  "name": "Cadastral",
  "rule": [
    {
      "title": "Receita Federal",
      "description": "Fonte atualizada mensalmente.",
      "homonym": false,
      "criticality": "high"
    },
  ]
},

enter image description here

2 个答案:

答案 0 :(得分:3)

尝试这个计算的道具。

filteredPolicyRules() {
  if (this.searchQuery) {
    return this.policyRules.group.reduce((groups, { name, rule }) => {
      const rules = [];

      rule.forEach(r => {
        if (r.title.startsWith(this.searchQuery)) {
          rules.push(r);
        }
      });

      if (rules.length > 0) {
        groups.push({
          name,
          rules
        });
      }

      return groups;
    }, []);
  }

  return this.policyRules;
}

我建议分别称它们为groupsrules(复数),以避免将来造成混淆-毕竟它们都是数组。

完整演示:

const policyRules = {
  "id": "rulesCompany",
  "group": [{
    "name": "Cadastral",
    "rule": [{
      "title": "Receita Federal",
      "description": "Fonte atualizada mensalmente.",
      "homonym": false,
      "criticality": "high"
    },
    {
      "title": "CNAE Primário - Alteração",
      "description": "Fonte atualizada mensalmente.",
      "homonym": false,
      "criticality": "high"
    },
    ]
  },
  {
    "name": "Dados modelados",
    "rule": [{
      "title": "Nível de Atividade - Alteração",
      "description": "Fonte atualizada mensalmente.",
      "homonym": false,
      "criticality": "high"
    },
    {
      "title": "Faturamento Presumido",
      "description": "Fonte atualizada mensalmente.",
      "homonym": false,
      "criticality": "medium"
    }
    ]
  }]
};

new Vue({
  el: '#app',

  data() {
    return {
      searchQuery: '',
      policyRules
    }
  },

  computed: {
    filteredPolicyRules() {
      if (this.searchQuery) {
        return this.policyRules.group.reduce((groups, { name, rule }) => {
          const rules = rule.filter(this.matchFilter);

          if (rules.length > 0) {
            groups.push({
              name,
              rules
            });
          }

          return groups;
        }, []);
      }

      return this.policyRules;
    }
  },

  methods: {
    matchFilter(item) {
      const
        search = this.searchQuery.toLowerCase(),
        term = (item.title || '').toLowerCase();

      return term.includes(search);
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <input v-model="searchQuery" placeholder="Search..." />
  <pre>{{ filteredPolicyRules }}</pre>
</div>

答案 1 :(得分:1)

因此,首先我将您的列表放入map变量中。然后,通过检查是否有任何所需的属性包含搜索项来进行过滤。 array.filter方法根据哪些条目返回true和false来返回一个新数组。

我正在检查内部名称,标题和描述。另外,我将所有内容都设为小写,因此大小写无关紧要。

Array.prototype.filter Reference


const term = 'CNE';

console.log(map.filter(e => {
  const { name } = e;
  if(contains(name, term)) return true;

  for(const _r of e.rule) {
    const { title, description } = _r;
    if(contains(title, term)) return true;
    if(contains(description, term)) return true;
  }
  return false;
}));

function contains(str, term) {
  return str.toLowerCase().includes(term.toLowerCase());
}

我也建议像Yom在他的回答中使用groupsrules,以便更好地命名。这样便是groups.filter(group => {[..]})for(const rule of group.rules)