如何将过滤器应用于嵌套数组?

时间:2019-07-21 18:28:58

标签: javascript arrays vue.js filter

我试图在多个数组上创建一个多重过滤器,但是我不知道如何在不复制嵌套数组的情况下对其进行过滤。我正在将vuejs与一些正在使用该数组的插件一起使用,所以我实际上不能更改它,只需过滤即可。

我正在使用draggablevue显示可以排序的数组列表。  我希望主数组保持不变,仅按名称或代码过滤“ inv”数组。 我已经使用过forEach,地图,过滤器,但是我找不到任何在线内容可以帮助解决此问题。

let invNameFilter = " cadeira";
let invCodeNameFilter = "1234";
let salas = [
        {
          name: "Sala 1.14",
          inv: [
            {
              name: "cadeira",
              inventoryCode: "1234"
            },
            {
              name: "quadro",
              inventoryCode: "4321"
            },
            {
              name: "mesa",
              inventoryCode: "1234"
            }
          ]
        },
        {
          name: "Sala 1.12",
          inv: [
            {
              name: "mesa",
              inventoryCode: "4321"
            },
            {
              name: "cadeira",
              inventoryCode: "4321"
            }
          ]
        }
      ];
let invNameFilter = " cadeira";
let invCodeNameFilter = "1234";
let salas = [
        {
          name: "Sala 1.14",
          inv: [
            {
              name: "cadeira",
              inventoryCode: "1234"
            },
            {
              name: "mesa",
              inventoryCode: "1234"
            }
          ]
        },
        {
          name: "Sala 1.12",
          inv: [
            {
              name: "cadeira",
              inventoryCode: "4321"
            }
          ]
        }
      ];

2 个答案:

答案 0 :(得分:0)

请注意,此代码不会覆盖初始salas数组。

new Vue({
  data() {
    return {
      name: "cadeira",
      code: "1234",
      salas: [{
          name: "Sala 1.14",
          inv: [{
              name: "cadeira",
              inventoryCode: "1234"
            },
            {
              name: "quadro",
              inventoryCode: "4321"
            },
            {
              name: "mesa",
              inventoryCode: "1234"
            }
          ]
        },
        {
          name: "Sala 1.12",
          inv: [{
              name: "mesa",
              inventoryCode: "4321"
            },
            {
              name: "cadeira",
              inventoryCode: "4321"
            }
          ]
        }
      ]
    }
  },
  computed: {
    filteredSalas() {
      // as alternative use _.deepClone (lodash function)
      const arr = JSON.parse(JSON.stringify(this.salas));

      arr.forEach(obj => {
        obj.inv = obj.inv.filter(item => item.name === this.name && item.inventoryCode === this.code);
      });

      return arr;
    }
  },
  template: "<div>{{ filteredSalas }}</div>"
}).$mount("#app");
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app"></div>

答案 1 :(得分:0)

假设您的对象结构保持不变,则可以混合使用mapfilterObject spread操作。

  • 地图(因为您需要所有外部对象)
  • 传播操作(要覆盖inv,因为它将被过滤)
  • inv进行过滤(应用过滤器函数以返回所需的结果)

const salas = [
  {
    name: "Sala 1.14",
    inv: [
      {
        name: "cadeira",
        inventoryCode: "1234"
      },
      {
        name: "quadro",
        inventoryCode: "4321"
      },
      {
        name: "mesa",
        inventoryCode: "1234"
      }
    ]
  },
  {
    name: "Sala 1.12",
    inv: [
      {
        name: "mesa",
        inventoryCode: "4321"
      },
      {
        name: "cadeira",
        inventoryCode: "4321"
      }
    ]
  }
];

const filteredSalas = salas.map(x => ({
                        ...x, 
                        inv: x.inv.filter(k => k.name === "cadeira" || k.inventoryCode === "1234") 
                      }))

console.log(filteredSalas);