TypeScript - 过滤对象及其完全相同的子对象中所有匹配的对象


软件开发中一个常见的任务是根据特定条件过滤对象。在本教程中,我们将探讨如何使用 TypeScript 过滤对象及其完全相同的子对象中所有匹配的对象。当处理复杂的数据结构或从嵌套对象中提取特定信息时,此技术特别有用。

我们将利用 TypeScript 的强大功能,例如类型注释和对象操作来实现这一点。

用于过滤匹配对象及其子对象的递归函数和类型保护

我们可以使用递归方法来过滤对象及其完全相同的子对象中所有匹配的对象。该算法将遍历对象及其子对象的属性,检查它们是否与过滤器值匹配。如果找到匹配项,则相应的属性或对象将包含在过滤后的结果中。

以下是所涉及步骤的概述:

  • 创建一个新的空对象来存储过滤后的结果。

  • 遍历输入对象的属性。

  • 对于每个属性,检查它是否与过滤器值匹配。

  • 如果该属性是一个对象,则在其上递归调用 filterMatchingObjects 函数。

  • 如果该属性是匹配项或包含匹配的子项,则将其添加到过滤后的结果对象中。

  • 返回过滤后的结果对象。

以下是一个示例:

function filterMatchingObjects(obj: any, filterValue: any): any {
   const filteredObj: any = {};
   for (const key in obj) {
      if (obj.hasOwnProperty(key)) {
         const value = obj[key];
         if (typeof value === "object" && value !== null) {
            lterMatchingObjects(value, filterValue);
         } else if (value === filterValue) {
            filteredObj[key] = value;
         }
      }
   }
   return Object.keys(filteredObj).length &g; 0 ? filteredObj : null;
}

示例 1

在此示例中,我们定义了一个表示每个产品对象结构的 Product 接口。然后,我们创建了一个名为 products 的 Product 对象数组。

定义数据后,我们对 product 数组使用了 filter() 方法。此方法采用一个回调函数,该函数检查每个产品的 category 属性是否与过滤器条件匹配,在本例中为“电子产品”。它创建一个名为 filteredProducts 的新数组,该数组仅包含类别为“电子产品”的产品。

用户可以在输出中观察到,filteredProducts 数组包含三个产品:“Macbook Pro”、“AirPods Pro”和“Kindle Paperwhite”。这些是满足过滤器条件的产品。用户可以在输出中观察到,filteredProducts 数组包含三个产品:“Macbook Pro”、“AirPods Pro”和“Kindle Paperwhite”。这些是满足过滤器条件的产品。

interface Product {
   name: string;
   category: string;
   price: number;
}

const products: Product[] = [
   { name: "Macbook Pro", category: "electronics", price: 2000 },
   { name: "AirPods Pro", category: "electronics", price: 249 },
   { name: "Leather Jacket", category: "clothing", price: 350 },
   { name: "Running Shoes", category: "footwear", price: 120 },
   { name: "Kindle Paperwhite", category: "electronics", price: 119 },
];

const filteredProducts = products.filter((product) =&g; product.category === "electronics");
console.log(filteredProducts)

编译后,它将生成以下 JavaScript 代码:

var products = [
   { name: "Macbook Pro", category: "electronics", price: 2000 },
   { name: "AirPods Pro", category: "electronics", price: 249 },
   { name: "Leather Jacket", category: "clothing", price: 350 },
   { name: "Running Shoes", category: "footwear", price: 120 },
   { name: "Kindle Paperwhite", category: "electronics", price: 119 },
];
var filteredProducts = products.filter(function (product) { return product.category === "electronics"; });
console.log(filteredProducts);

输出

以上代码将产生以下输出:

[
  { name: 'Macbook Pro', category: 'electronics', price: 2000 },
  { name: 'AirPods Pro', category: 'electronics', price: 249 },
  { name: 'Kindle Paperwhite', category: 'electronics', price: 119 }
]

示例 2

在此示例中,我们定义了一个表示每个用户对象结构(包括其偏好)的 User 接口。我们创建了一个名为 users 的 User 对象数组。然后,为了根据用户的暗模式偏好过滤用户,我们定义了 filterMatchingObjects 函数。此函数采用一个 User 对象数组和一个 filterValue(表示暗模式偏好的布尔值)作为参数。

在函数内部,我们遍历每个 User 对象并检查其偏好的 darkMode 属性是否与 filterValue 匹配。如果找到匹配项,则将用户添加到 filteredUsers 数组中。

在输出中,用户可以观察到 usersWithDarkMode 数组仅包含已启用 darkMode 偏好的用户对象。

// Create the User interface
interface User {
   name: string;
   age: number;
   email: string;
   preferences: {
      theme: string;
      darkMode: boolean;
      notifications: number;
   };
}

// Create an array of User objects
const users: User[] = [
   {
      name: "John Doe",
      age: 25,
      email: "[email protected]",
      preferences: {
         theme: "light",
         darkMode: true,
         notifications: 5,
      },
   },
   {
      name: "Jane Smith",
      age: 30,
      email: "[email protected]",
      preferences: {
         theme: "dark",
         darkMode: false,
         notifications: 10,
      },
   },
];

const filterMatchingObjects = (users: User[], filterValue: boolean): User[] => {
   const filteredUsers: User[] = []; 
   for (const user of users) {
      if (user.preferences.darkMode === filterValue) {
         filteredUsers.push(user);
      }
   } 
   return filteredUsers;
}; 
const usersWithDarkMode = filterMatchingObjects(users, true); 
console.log(usersWithDarkMode);

编译后,它将生成以下 JavaScript 代码:

// Create an array of User objects
var users = [
   {
      name: "John Doe",
      age: 25,
      email: "[email protected]",
      preferences: {
         theme: "light",
         darkMode: true,
         notifications: 5
      }
   },
   {
      name: "Jane Smith",
      age: 30,
      email: "[email protected]",
      preferences: {
         theme: "dark",
         darkMode: false,
         notifications: 10
      }
   },
];
var filterMatchingObjects = function (users, filterValue) {
   var filteredUsers = [];
   for (var _i = 0, users_1 = users; _i < users_1.length; _i++) {
      var user = users_1[_i];
      if (user.preferences.darkMode === filterValue) {
         filteredUsers.push(user);
      }
   }
   return filteredUsers;
};
var usersWithDarkMode = filterMatchingObjects(users, true);
console.log(usersWithDarkMode);

输出

以上代码将产生以下输出:

[
   {
      name: 'John Doe',
      age: 25,
      email: '[email protected]',
      preferences: { theme: 'light', darkMode: true, notifications: 5 }
   }
]

示例 3

在此示例中,我们创建了一个由嵌套对象结构表示的文件系统。文件系统中的每个对象都具有一个 name 属性和一个可选的 children 属性,该属性包含一个嵌套文件系统对象的数组。

定义文件系统结构后,我们实现了 filterMatchingObjects 函数。此函数根据指定的过滤器值递归地过滤文件系统对象及其子对象。它创建一个名为 filteredObj 的新对象来存储过滤后的结果。

为了执行过滤,该函数检查当前对象是否具有子对象。如果是,则它会遍历每个子对象,并在其上递归调用 filterMatchingObjects 函数。然后,它会过滤掉所有空值,只保留过滤后的子对象。如果有过滤后的子对象,则将其添加到 filteredObj 中。

该函数还会检查当前对象的名称是否与过滤器值匹配,或者它是否具有任何过滤后的子对象。如果任一条件为真,则返回 filteredObj。否则,返回 null。

用户可以观察输出以查看 filteredFileSystem 对象仅包含与过滤器值“file6.txt”匹配的文件系统对象及其完全相同的子对象。

interface FileSystemObject {
   name: string;
   children?: FileSystemObject[];
} 
function filterMatchingObjects(obj: FileSystemObject, filterValue: string): FileSystemObject | null {
   const filteredObj: FileSystemObject = { name: obj.name }; 
   if (obj.children) {
      const filteredChildren: FileSystemObject[] = obj.children
      .map(child => filterMatchingObjects(child, filterValue))
      .filter(child => child !== null) as FileSystemObject[]; 
      if (filteredChildren.length > 0) {
         filteredObj.children = filteredChildren;
      }
   } 
   if (obj.name === filterValue || (filteredObj.children && filteredObj.children.length > 0)) {
      return filteredObj;
   }
   return null;
} 

// Example usage
const fileSystem: FileSystemObject = {
   name: "root",
   children: [
      {
         name: "folder1",
         children: [
            { name: "file1.txt" },
            { name: "file2.txt" },
            { name: "file3.ts" }
         ]
      },
      {
         name: "folder2",
         children: [
            { name: "file4.js" },
            { name: "file5.ts" },
            { name: "file6.txt" }
         ]
      }
   ]
}; 
const filteredFileSystem = filterMatchingObjects(fileSystem, "file6.txt");
console.log(filteredFileSystem);

编译后,它将生成以下 JavaScript 代码:

function filterMatchingObjects(obj, filterValue) {
   var filteredObj = { name: obj.name };
   if (obj.children) {
      var filteredChildren = obj.children
      .map(function (child) { return filterMatchingObjects(child, filterValue); })
      .filter(function (child) { return child !== null; });
      if (filteredChildren.length > 0) {
         filteredObj.children = filteredChildren;
      }
   }
   if (obj.name === filterValue || (filteredObj.children && filteredObj.children.length > 0)) {
      return filteredObj;
   }
   return null;
}
// Example usage
var fileSystem = {
   name: "root",
   children: [
      {
         name: "folder1",
         children: [
            { name: "file1.txt" },
            { name: "file2.txt" },
            { name: "file3.ts" }
         ]
      },
      {
         name: "folder2",
         children: [
            { name: "file4.js" },
            { name: "file5.ts" },
            { name: "file6.txt" }
         ]
      }
   ]
};
var filteredFileSystem = filterMatchingObjects(fileSystem, "file6.txt");
console.log(filteredFileSystem);

输出

以上代码将产生以下输出:

{ name: 'root', children: [ { name: 'folder2', children: [Array] } ] }

在本教程中,用户学习了如何使用 TypeScript 过滤对象及其完全相同的子对象中所有匹配的对象。通过使用递归函数和 filter 方法,我们可以轻松地搜索大型对象并提取所需的数据。这在数据管理至关重要的大型 Web 应用程序中尤其有用。

更新于:2023 年 8 月 21 日

2K+ 次查看

启动你的 职业生涯

通过完成课程获得认证

开始
广告