通过相同属性的值用其他对象过滤对象

时间:2018-07-17 18:56:01

标签: javascript arrays json filter

我想通过文本输入字段过滤JSON数据,该数据用于动态创建表。每个表头都有其自己的输入字段。

像这样想象表数据:

var data = [{
    id: "1",
    A: "10",
    B: "100",
    C: "1000",
    description: "number 1"
  },
  {
    id: "2",
    A: "20",
    B: "200",
    C: "2000",
    description: "number 2"
  },
  {
    id: "3",
    A: "30",
    B: "300",
    C: "3000",
    description: "number 3"
  }
]

我的输入存储在一个单独的对象中,如下所示:

var filterColumnKeys = {
  A: "20",
  B: "43"
}

该对象包含基于表头(由表数据动态创建)的搜索输入(值)和键。

我需要使用这两个搜索输入(20和43)过滤表数据中的每个对象,因此仅显示与搜索输入匹配的对象(=表中的行)。键入时过滤应该是即时的,因此也应该显示部分匹配的短语。

示例1:什么也不会显示:

var filterColumnKeys = {
  A: "20",
  B: "43"
}

示例2:将显示ID为2的对象:

var filterColumnKeys = {
  A: "20",
}

示例3:将显示所有对象:

var filterColumnKeys = {
  B: "00",
}

编辑:我已经具有使用一个过滤键过滤整个表的功能:

// filter whole table by filter input field
if (filterKey) {
  data = data.filter(function(item) {
    var dataKeys = Object.keys(item);
    return dataKeys.some(function(key) {
      var itemValue = String(item[key]).toLowerCase();
      // int (-1 if not found)
      var itemFound = itemValue.indexOf(filterKey);
      var shouldBeFiltered = itemFound > -1;
      return shouldBeFiltered;
    });
  });
}

..但是在使用filterColumnKeys数组的每个键时,将其定义为仅通过键(=表的列)仅通过相应的数据对象检查每个输入是不起作用的。

3 个答案:

答案 0 :(得分:0)

try solution

TS:

A:any='';
  B:any='';

  arr: Array<any> = [{
    id: "1",
    A: "10",
    B: "100",
    C: "1000",
    description: "number 1"
  },
  {
    id: "2",
    A: "20",
    B: "200",
    C: "2000",
    description: "number 2"
  },
  {
    id: "3",
    A: "30",
    B: "300",
    C: "3000",
    description: "number 3"
  }
  ]

  data: any;
  filterData(a,b){

    if(a == "00" || b == "00"){
    this.data = this.arr;
    } else if( a == '' || b == ''){
    this.data = this.data = this.arr.find(obj => obj.A == a || obj.B == b)

    } else if( a != '' && b != '' ){
    this.data = this.arr.find(obj => obj.A == a && obj.B == b)

    }

  }

答案 1 :(得分:0)

您可以使用Array.prototype.filter并遍历每个项目,并检查它们中是否包含相应的键和值:

var data=[{id:"1",A:"10",B:"100",C:"1000",description:"number 1"},{id:"2",A:"20",B:"200",C:"2000",description:"number 2"},{id:"3",A:"30",B:"300",C:"3000",description:"number 3"}];

var filterColumnKeys = {
  A: "20"
}


function getFilteredData(data, filterColumnKeys) {

    const fKeys = Object.keys(filterColumnKeys);

    const filtered = data.filter(item => {

        const isMatch = fKeys.every(k => {
            return filterColumnKeys[k] === '00' || item[k] === filterColumnKeys[k];
        })

        return isMatch;

    });

    return filtered;

}

const result = getFilteredData(data, filterColumnKeys);

console.log(result);

答案 2 :(得分:0)

感谢答案和启发,我修改了ASDFGerte对最初问题的评论,并对其进行了一些修改:

  if (filterColumnKeys) {
    if (Object.keys(filterColumnKeys).length !== 0) {
      data = data.filter(e =>
        Object.keys(filterColumnKeys).every(key =>
          String(e[key])
            .toLowerCase()
            .includes(String(filterColumnKeys[key]).toLowerCase())
        )
      );
    }
  }

我的主要问题之一是表头消失了。每次搜索短语与第一个输入的任何数据都不匹配时,表标题都会被隐藏,这也会隐藏文本输入字段,因此该短语无法更改。

我添加了检查以防止标题隐藏,并且短语值匹配检查是使用小写字符串完成的。

通过此解决方案,我还可以使用多个输入字段来同时过滤数据(还包括部分匹配的短语)。