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对象数组。
在定义数据之后,我们利用了产品数组上的filter()方法。该方法接受一个回调函数,检查每个产品的category属性是否与筛选条件相匹配,这里是”electronics”。它创建了一个名为filteredProducts的新数组,只包含category为”electronics”的产品。
用户可以在输出中观察到,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数组只包含夜间模式偏好已启用的用户对象。
// 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: "john.doe@example.com",
preferences: {
theme: "light",
darkMode: true,
notifications: 5,
},
},
{
name: "Jane Smith",
age: 30,
email: "jane.smith@example.com",
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: "john.doe@example.com",
preferences: {
theme: "light",
darkMode: true,
notifications: 5
}
},
{
name: "Jane Smith",
age: 30,
email: "jane.smith@example.com",
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: 'john.doe@example.com',
preferences: { theme: 'light', darkMode: true, notifications: 5 }
}
]
示例3
在这个例子中,我们创建了一个由嵌套对象结构表示的文件系统。文件系统中的每个对象都有一个名字属性和一个可选的 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应用程序中特别有用,其中数据管理至关重要。