简体   繁体   English

JavaScript 字符串搜索对象数组

[英]JavaScript string search for array of objects

  • I need to implement a search function for a table.我需要为一个表实现一个搜索功能。
  • I got an array of objects with unnecessary object properties.我得到了一组具有不必要的对象属性的对象。
  • I need to map the array to get necessary properties and then do the filtration.我需要映射数组以获得必要的属性,然后进行过滤。

This is my code.这是我的代码。

 const items = [ { name: 'pathum', id: 1, status: true, createdAt: 'KKKK', country: { name: 'SL', code: 12, }, }, { name: 'kasun', id: 1, status: true, createdAt: 'KKKK', country: { name: 'USA', code: 23, }, }, { name: 'hansi', id: 1, status: true, createdAt: 'KKKK', country: { name: 'GERMANY', code: 34, }, }, ]; const tableColumns = ['name', 'country.name']; const onSearch = (e) => { e = e.toLowerCase(); const mappedItems = items.map((item) => { Object.keys(item).forEach((key) => { if (!tableColumns.includes(key)) delete item[key]; }); return item; }); if (e) { const result = mappedItems.filter((item) => { const str = JSON.stringify(item).toLowerCase(); if (str.search(e) >= 0) return item; }); return result; } else { return mappedItems; } }; console.log(onSearch('GERMANY'));

In an item object, I only need to get these two fields在一个 item 对象中,我只需要获取这两个字段

const tableColumns = ['name', 'country.name'];

But this only gives me the name property但这只给了我 name 属性

const mappedItems = items.map((item) => {
    Object.keys(item).forEach((key) => {
      if (!tableColumns.includes(key)) delete item[key];
    });
    return item;
  });

My first question is how to map to expect a result like this我的第一个问题是如何映射以期望这样的结果

  {
    name: 'pathum',
    country: {
      name: 'SL',
    },
  },

Second question is JSON.stringtfy map whole object.第二个问题是JSON.stringtfy映射整个对象。 So If I search "name" it will return all the objects becasue "name" is there in the all records in the stringtify string.因此,如果我搜索“name”,它将返回所有对象,因为 stringtify 字符串中的所有记录中都存在“name”。

How do I avoid keys in the object when doing the stringify?进行字符串化时如何避免对象中的键?

Hope my question is clear to you all.希望我的问题对你们都很清楚。

How do I modify this code to get that expected functionality?如何修改此代码以获得预期的功能?

const tableColumns = ['name', 'country'];
const deleteProp = ['code'];

const mappedItems = items.map((item) => {
Object.keys(item).forEach((key) => {
console.log(key);
  if (!tableColumns.includes(key)) delete item[key];
  if(key == 'country') delete item[key][deleteProp[0]];
});
return item;
});

This may answer your first question.这可能会回答您的第一个问题。

You can check if the object has any of the tableColumns paths which includes the searched text.您可以检查对象是否具有任何包含搜索文本的tableColumns路径。 And then get a subset of the filtered objects and only include the tableColumns properties然后获取过滤对象的子集,只包含tableColumns属性

 const items=[{name:"pathum",id:1,status:true,createdAt:"KKKK",country:{name:"SL",code:12,},},{name:"kasun",id:1,status:true,createdAt:"KKKK",country:{name:"USA",code:23,},},{name:"hansi",id:1,status:true,createdAt:"KKKK",country:{name:"GERMANY",code:34}}], tableColumns = ['name', 'country.name']; function onSearch(array, e) { const output = []; for (const o of array) { const hasProp = tableColumns.some(path => getProperty(o, path).includes(e)) if (hasProp) output.push(subSet(o, tableColumns)) } return output } function getProperty(o, path) { return path.split('.').reduce((acc, p) => acc?.[p], o) || '' } function subSet(o, paths) { const output = {} for (const path of paths) { let keys = path.split('.'), last = keys.pop(), value = o; const final = keys.reduce((acc, k) => { value = value?.[k] return acc[k] ||= {} }, output); final[last] = value?.[last]; } return output; } console.log(onSearch(items, 'pat')); console.log(onSearch(items, 'kasun'));

First, don't change data.首先,不要更改数据。 You can clone the data and change it.您可以克隆数据并进行更改。 And, search should be search.而且,搜索应该是搜索。 Don't put the data formation in it.不要把数据格式放在里面。

Let's start.开始吧。

 const items = [ { name: 'pathum', id: 1, status: true, createdAt: 'KKKK', country: { name: 'SL', code: 12, }, }, { name: 'kasun', id: 1, status: true, createdAt: 'KKKK', country: { name: 'USA', code: 23, }, }, { name: 'hansi', id: 1, status: true, createdAt: 'KKKK', country: { name: 'GERMANY', code: 34, }, }, ]; // We will use object to get the fields you want. To reuse, you can add more fields you want. const tableColumns = { // id: 1, name: 1, country: { name: 1 } } // getting the mapped items const mappedItems = items.map((item) => { const temp = {}; Object.keys(item).forEach((key) => { const target = tableColumns[key]; if (target) { if (typeof target === 'number'){ temp[key] = item[key]; } else { temp[key] = {}; Object.keys(target).forEach(subKey => temp[key][subKey] = item[key][subKey]); } } }); return temp; }); // search function, use local varibles const onSearch = (array, countryName) => { return array.find(element => element.country.name.toLowerCase() === countryName.toLowerCase()) } const searchResult = onSearch(mappedItems, 'germany'); console.log(searchResult);

You can just create a new array using Array.map您可以使用Array.map创建一个新数组

 const items = [{ name: 'pathum', id: 1, status: true, createdAt: 'KKKK', country: { name: 'SL', code: 12, }, }, { name: 'kasun', id: 1, status: true, createdAt: 'KKKK', country: { name: 'USA', code: 23, }, }, { name: 'hansi', id: 1, status: true, createdAt: 'KKKK', country: { name: 'GERMANY', code: 34, }, }, ]; let minItems = items.map(function(item) { return { "name": item.name, "country": { "name": item.country.name } } }); console.log(minItems);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM