Javascript 嵌套数组中的过滤

Javascript 嵌套数组中的过滤,javascript,knockout.js,Javascript,Knockout.js,我有一个嵌套的数据结构映射到knockout JS中的数组: class Departments{ string DepartmentName; List<Group> groups } class Group{ string groupName; List<Person> persons; } class Person{ String Firsname; string LastName; } 现在我想在文本框

我有一个嵌套的数据结构映射到knockout JS中的数组:

class Departments{
     string DepartmentName;
     List<Group> groups
}
class Group{
     string groupName;
     List<Person> persons;
}
class Person{
     String Firsname;
     string LastName;
}
现在我想在文本框中键入
search\u FirstName
时自动过滤数据。现在,我可以使用以下代码根据
部门名称
筛选记录:

self.Profiles = ko.computed(function () {
        return ko.utils.arrayFilter(self.BackupProfiles(), function (rec) {
            return (
                (self.search_FirstName().length == 0 || rec.DepartmentName.indexOf(self.search_FirstName()) > -1)
            );
        });
    });

有人知道如何根据firstname和lastname字段过滤记录吗

如果我理解正确,您希望“展平”整个结构,这样您就有了一个包含DepartmentName和GroupName字段的人员数组。要使计算的
正常工作,原始结构的每个级别都必须是
可观察的数组
。计算的结果将类似于:

var flattenedPeople = ko.computed(function () {
  var result = [];
    ko.utils.arrayForEach(self.BackupProfiles(), function (dept) {
      ko.utils.arrayForEach(dept.groups(), function (group) {
        ko.utils.arrayForEach(group.persons(), function (person) {
          result.push({
            DepartmentName: dept.DepartmentName,
            GroupName: group.GroupName,
            FirstName: person.FirstName,
            LastName: person.LastName
        });
      });
    });
  return result;
});
然后,您可以创建一个与FirstName和/或Lastname匹配的计算结果:

self.filteredPeople = ko.computed(function () {
  var first = self.search_FirstName(),
      last = self.search_LastName();
  return ko.utils.arrayFilter(flattenedPeople(), function (rec) {
    return ( first === '' || rec.FirstName === first ) &&
      (last === '' || rec.LastName === last );
  });
});
我已经为你创造了。其核心的
computed
构建了一个类似Profiles结构的结构,但只包括匹配的记录

vm.filteredProfiles = ko.computed(function () {
    var first = vm.search_FirstName().toLocaleLowerCase();
    if (first === '') return vm.Profiles();
    var result = [];
    ko.utils.arrayForEach(vm.Profiles(), function (dept) {
        var groupsMatched = [];
        ko.utils.arrayForEach(dept.GroupVMs(), function (group) {
            var personsMatched = [];
            ko.utils.arrayForEach(group.PersonPhonesVMs(), function (person) {
                if (person.FirstName().toLocaleLowerCase().indexOf(first) > -1) {
                    personsMatched.push(person);
                }
            });
            if (personsMatched.length > 0) {
                groupsMatched.push({
                    GroupName: group.GroupName,
                    PersonPhonesVMs: personsMatched
                });
            }
        });
        if (groupsMatched.length > 0) {
            result.push({
                DepartmentName: dept.DepartmentName,
                GroupVMs: groupsMatched
            });
        }
    });

    return result;
});

你当前的代码对我来说毫无意义。为什么你要将
部门名称
搜索名
进行比较,这是两件不同的事情不?为什么要使用
indexOf
而不是
localeCompare
?你在最后一句话中提出的任务的实际问题是什么?你就不能直接去做吗?请尝试使用更完整的example.PS更新您的问题。我已将“asp.NETMVC”标记替换为“javascript”。我意识到当前的第一段代码是c#,但我强烈建议将其更改为应用程序的javascript,因为这个问题似乎与服务器端代码无关。如果这是一个错误,请随意回滚标记编辑,但如果是,请同时澄清“asp.net mvc”与问题的相关性。我想表明我可以按第一级搜索,但不能继续在内部级搜索。比较search_FirstName和departmentName没有任何意义。@Jeroen首先,我从由ASP.Net实现的服务器获取全部数据。当然,您可以从ASP.Net获取数据。但是,如果后端是PHP或localStorage,您的问题会改变或消失吗?从你的问题来看,我想不是。如果您不必处理服务器端技术,只需重新编写JavaScript,我们将更容易为您提供帮助。您可能会将实际搜索条件改进为
!first | | rec.FirstName.tolocalLowercase().indexOf(first)>-1
@Roy J:谢谢!!!但我不想把整个阵列压扁。我想保持结构不变,并按姓名搜索人员。最后,删除所有没有匹配人员的部门和/或组。通过计算不会丢失原始结构。您可以在另一个计算机中使用
filteredPeople
来筛选部门和组。建立你需要的工具。如果您包括HTML及其工作方式,我可以给您提供更具体的帮助。@Joy J我还通过添加HTML代码来补充这个问题。请帮帮我!!!
vm.filteredProfiles = ko.computed(function () {
    var first = vm.search_FirstName().toLocaleLowerCase();
    if (first === '') return vm.Profiles();
    var result = [];
    ko.utils.arrayForEach(vm.Profiles(), function (dept) {
        var groupsMatched = [];
        ko.utils.arrayForEach(dept.GroupVMs(), function (group) {
            var personsMatched = [];
            ko.utils.arrayForEach(group.PersonPhonesVMs(), function (person) {
                if (person.FirstName().toLocaleLowerCase().indexOf(first) > -1) {
                    personsMatched.push(person);
                }
            });
            if (personsMatched.length > 0) {
                groupsMatched.push({
                    GroupName: group.GroupName,
                    PersonPhonesVMs: personsMatched
                });
            }
        });
        if (groupsMatched.length > 0) {
            result.push({
                DepartmentName: dept.DepartmentName,
                GroupVMs: groupsMatched
            });
        }
    });

    return result;
});