【问题标题】:JavaScript string search for array of objectsJavaScript 字符串搜索对象数组
【发布时间】:2020-11-03 19:24:18
【问题描述】:
  • 我需要实现一个表格的搜索功能。
  • 我得到了一组具有不必要对象属性的对象。
  • 我需要映射数组以获得必要属性,然后进行过滤。

这是我的代码。

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'));

在一个item对象中,我只需要获取这两个字段

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

但这只会给我 name 属性

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

我的第一个问题是如何映射以期望得到这样的结果

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

第二个问题是JSON.stringtfy 映射整个对象。因此,如果我搜索“name”,它将返回所有对象,因为 stringtify 字符串的所有记录中都存在“name”。

在进行字符串化时如何避免对象中的键?

希望大家都清楚我的问题。

如何修改此代码以获得预期的功能?

【问题讨论】:

  • 您要搜索所有属性还是只搜索tableColumns 属性?例如:如果您搜索"KKKK",是否要返回所有对象,因为它们都有createdAt,但它不包含在tableColumns
  • @adiga 我只搜索tableColumns
  • 您是在尝试修改原始 items 数组还是尝试在不修改原始数组的情况下创建新数组?

标签: javascript


【解决方案1】:
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;
});

这可能会回答您的第一个问题。

【讨论】:

    【解决方案2】:

    您可以检查对象是否具有包含搜索文本的任何tableColumns 路径。然后获取过滤对象的子集并且只包含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'));

    【讨论】:

      【解决方案3】:

      首先,不要更改数据。您可以克隆数据并进行更改。 而且,搜索应该是搜索。不要把数据形成放在里面。

      让我们开始吧。

      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);

      【讨论】:

        【解决方案4】:

        你可以使用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);

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-05-19
          • 1970-01-01
          • 1970-01-01
          • 2013-10-27
          • 1970-01-01
          • 2016-01-28
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多