过滤 JSON 数组,使用字符串搜索在任何属性上:TypeScript

huangapple go评论65阅读模式
英文:

Filter a JSON array with a string search on any property: TypeScript

问题

我有一个Json对象数组,我正在将它绑定到一个表格。

我想要过滤JSON数组,并仅返回那些属性值与输入字符串的匹配关键字相同的对象。

这是我的示例JSON:

[{
      "TransactionID": "1",
      "MyProperty1": "some data 1",
      "MyProperty2": "28-02-2023",
      "MyProperty3": "some more data 1",
      "MyProperty4": "some other data 1",
      "documents": [
                      {"TransactionID": "1","MyProperty1":"Document 1","MyProperty2":"Completed"},
                      {"TransactionID": "1","MyProperty1":"Document 2","MyProperty2":"In Progress"},
                      {"TransactionID": "1","MyProperty1":"Document 3","MyProperty2":"In Progress"}
                   ]
    }, 
    {
      "TransactionID": "2",
      "MyProperty1": "some data 2",
      "MyProperty2": "27-02-2023",
      "MyProperty3": "some more data 2",
      "MyProperty4": "some other data 2",
      "documents":  [ 
                   {"TransactionID": "2","MyProperty1":"Document 1","MyProperty2":"Completed"},
                   {"TransactionID": "2","MyProperty1":"Document 2","MyProperty2":"Completed"}
                ]
    }];

我尝试过这样做,但抛出了这个错误 元素隐式具有 'any' 类型,因为类型为 'string' 的表达式不能用于索引类型为 'Object' 的对象

doFilter(filterText: string) {
    
   let filteredObject = this.engagementData.filter(o =>
      Object.keys(o).some(k => o[k].toLowerCase().includes(filterText.toLowerCase())));
       
  }

这里我的数据包含上述的JSON。

有人可以建议我是否遗漏了什么吗?

我知道循环遍历每个JSON对象的每个属性是其中一个选项,

但如果有任何内置函数可以检索具有特定字符串的JSON对象中的所有对象,那将很有帮助。

英文:

I have a Json object array which I am binding to a grid.

I want to filter the JSON array and return only those objects whose properties' values have a matching keyword as that of an input string.

This is my sample JSON

[{
      "TransactionID": "1",
      "MyProperty1": "some data 1",
      "MyProperty2": "28-02-2023",
      "MyProperty3": "some more data 1",
      "MyProperty4": "some other data 1",
      "documents": [
                      {"TransactionID": "1","MyProperty1":"Document 1","MyProperty2":"Completed"},
                      {"TransactionID": "1","MyProperty1":"Document 2","MyProperty2":"In Progress"},
                      {"TransactionID": "1","MyProperty1":"Document 3","MyProperty2":"In Progress"}
                   ]
    }, 
    {
      "TransactionID": "2",
      "MyProperty1": "some data 2",
      "MyProperty1": "27-02-2023",
      "MyProperty1": "some more data 2",
      "MyProperty1": "some other data 2",
      "documents":  [ 
                       {"TransactionID": "2","MyProperty1":"Document 1","MyProperty1":"Completed"},
                       {"TransactionID": "2","MyProperty1":"Document 2","MyProperty1":"Completed"}
                    ]
    }];

I have tried doing this, but throws this error 'Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'Object'

    doFilter(filterText: string) {
    
   let filteredObject = this.engagementData.filter(o =>
      Object.keys(o).some(k => o[k].toLowerCase().includes(filterText.toLowerCase())));
       
  }

Here my data has the above JSON.

Can someone suggest if there is something I am missing?

I am aware that looping through each property of each of the JSON Object is one of the options

but it will be helpful if there are any inbuilt functions which can retrieve all objects from JSON which has a specific string in any of the object's property

答案1

得分: 0

如果您的 this.engagementDataobject 类型,那么您不能在其上调用 string 方法,因此不能调用 .toLowerCase(),这就是错误提示您的原因。

如果您正在尝试筛选具有与您搜索的文本匹配的属性的 objects,那么您应该检查该 object 的所有 values

let filteredObject = this.engagementData.filter(o =>
    Object.keys(o).some(k => Object.values(o[k]).some(val => val.toLowerCase().includes(filterText.toLowerCase())));

您需要在 o[k] 对象的每个值上调用 toLowerCase().includes(),而不是在 o[k] 上调用。

注意:

这适用于 object 类型,如果 o[k] 可以是 array 或其他类型,您需要检查 o[k] 的类型并根据需要调整代码。

英文:

If your this.engagementData is of type object, then you can't call a string method on it, so you can't call .toLowerCase()on it, and that's what the error is telling you.

And if you are trying to filter objects which have a property matching your searched text then you should check on all values of that object:

let filteredObject = this.engagementData.filter(o =>
    Object.keys(o).some(k => Object.values(o[k]).some(val => val.toLowerCase().includes(filterText.toLowerCase())));

You need to call toLowerCase() and .includes() on each value of the o[k] object properties, instead of o[k].

Note:

This is the case for object types, if o[k] can be of type array or other types, you need to check over the type of o[k] and adapt the code for that.

答案2

得分: 0

我相信你的错误与这个答案相同
https://stackoverflow.com/questions/57086672/element-implicitly-has-an-any-type-because-expression-of-type-string-cant-b

你需要指定 k 的类型

英文:

I believe that your error is the same of this answer
https://stackoverflow.com/questions/57086672/element-implicitly-has-an-any-type-because-expression-of-type-string-cant-b

You need to specify the type of k

huangapple
  • 本文由 发表于 2023年3月9日 21:52:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/75685543.html
  • angular
  • javascript
  • json
  • typescript

我可以将 “ :?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定