1

应用场景

一个表格的过滤筛选,可能涉及多个筛选条件,this.filter里面存的是所有筛选条件的v-model状态的一个对象,this.tableData是从后端获取的所有原始表格数据的数组,this.filteredTableData是过滤后的表格数据的数组。

代码

    filterTableData() {
      this.filteredTableData = this.tableData.map((item, index) => {
        Object.keys(this.filter).forEach(key => {
          if (this.filter[key] && item[key] && item[key] === this.filter[key]) {
            console.log(item)
            return item
          }
        })
      })
      console.log(this.filteredTableData)
      // this.paginateTableData()
    },

问题

这样写,会使得第二个console.log(this.filteredTableData)拿到一个全部是undefined的数组。这样的错误应该是因为forEach没法用return 跳出循环。
所以我想知道

  • 在使用map 且map内部最好不使用变量(使用也行吧,只是担心性能)的情况下,如何实现这个函数?

  • 如果this.filteredTableData的数据量特别大,有没有什么更好的办法?

2017-05-02 提问
8 个回答
2

直接用 [].filter 啊...

1

你不是苦恼会返回undefined么? 用filter就不会啊...

死胖子 · 2017-05-02

展开评论
1

我回答你数组里都是undefined的问题吧。

你在map函数里 没有return 当然就不会有返回值啊,没有显示的返回值当然是undefined。

相当于你遍历的结果没有返回 做了无用功。

map的回调函数不应该这么写么?

(item, index) => {
    return Object.keys(this.filter).forEach(key => {
        if (this.filter[key] && item[key] && item[key] === this.filter[key]) {
            console.log(item)
            return item
        }
    })
}

当我没有回答吧,又看了一遍,你是知道这个问题的。return Object.keys(this.filter) 对你这来说没有意义。

还是需要使用个中间变量的,如:

this.filteredTableData = this.tableData.map((item, index) => {
    var _item;
    Object.keys(this.filter).forEach(key => {
        if (this.filter[key] && item[key] && item[key] === this.filter[key]) {
            console.log(item)
            _item = item;
            // return item
        }
    })
    return _item
})

// 你要考虑声明变量的性能损失的话 可以在外层声明好 用完 释放掉。

var _item;
this.filteredTableData = this.tableData.map((item, index) => {
    Object.keys(this.filter).forEach(key => {
        if (this.filter[key] && item[key] && item[key] === this.filter[key]) {
            console.log(item)
            _item = item;
            // return item
        }
    })
    return _item
})
_item = null
0

题主的问题有点难懂
若想把map转为数组
只需要输入 [...map] 即可

0

filter更为恰当。

另外,加一个变量就会影响性能的观点从何而来。不要在还没出现任何性能问题之时就靠猜测它会有性能问题。

要么你就用普通的for循环代替,要么你就得在forEach外面定义一个bool值来判断。

0

我之前遇到过使用 map 和 forEach 带来的问题,后来都合理的使用 for...in 和 for...of 来解决掉了,你是不是可以换一下思路,不一定要用 map 和 forEach 来解决。

0

不要再forEach里用this

filterTableData() {
      var that = this;
      this.filteredTableData = this.tableData.map((item, index) => {
        Object.keys(that.filter).forEach(key => {
          if (that.filter[key] && item[key] && item[key] === that.filter[key]) {
            console.log(item)
            return item
          }
        })
      })
      console.log(this.filteredTableData)
      // this.paginateTableData()
    },
0

不知道你是不是这个意思。


filterTableData () {
    this.filteredTableData = this.tableData.filter((item, index) => {
      return Object.keys(this.filter).some(key => this.filter[key] && item[key] && item[key] === this.filter[key])
    })
    console.log(this.filteredTableData)
    // this.paginateTableData()
}
0

最近也碰到了这个需求,这个需求具体是需要从json对象数组导出到excel文件,使用xlsx插件.
在导出前需要将对象数据数组转化为数组-数组的格式,并且只筛选出给定的字段例如:

//给定字段: 
var filterList = ["foo", "bar"]

//给定的对象数组jsonData
var jsonData = [
  {foo: "foo1", bar: "bar1", baz: "baz1"},
  {foo: "foo2", bar: "bar2", baz: "baz2"},
]

//转化后的数组-数组
var sheetArray[
  ["foo1", "bar1"],
  ["foo2", "bar2"],
]

根据题主的描述来看,题主的需求与我的需求是一致的.首先,题主的this.filter完全没必要是一个对象,需要改为一个数组.然后,可以用以下写法:

function formatJson(filterVal, jsonData) {
  return jsonData.map(v => {
    return filterVal.map(j => {
      return v[j]
    })
  })
}

撰写答案

推广链接