繁体   English   中英

使用嵌套对象递归过滤数组

[英]Recursively filtering array with nested objects

我有一些看起来像这样的数据:

  {
    _id: "5e985a07feddae7617ac44f6",
    age: 24,
    eyeColor: "brown",
    name: "Cummings Baxter",
    gender: "male",
    company: "VELOS",
    email: "cummingsbaxter@velos.com",
    phone: "+1 (907) 482-2451",
    tags: ["labore", "elit", "excepteur", "nisi", "mollit", "anim", "aliquip"],
    friends: [
      {
        id: 0,
        name: "Sheppard Jensen",
      },
    ],
  },
  {
    _id: "5e985a0709dfa1e6fd93c6ad",
    age: 32,
    eyeColor: "brown",
    name: "Madelyn Dickson",
    gender: "female",
    company: "KENGEN",
    email: "madelyndickson@kengen.com",
    phone: "+1 (984) 521-2439",
    tags: ["nisi", "veniam", "dolore", "officia", "ex", "non", "pariatur"],
    friends: [
      {
        id: 0,
        name: "Bruce Barton",
      },
      {
        id: 1,
        name: "Juliet Schmidt",
      },
      {
        id: 2,
        name: "Horton Haley",
      },
      {
        id: 3,
        name: "Herminia Witt",
      },
    ],
  },
  {
    _id: "5e985a0737e2306e9aef6ecd",
    age: 26,
    eyeColor: "blue",
    name: "Mcguire Mercado",
    gender: "male",
    company: "LINGOAGE",
    email: "mcguiremercado@lingoage.com",
    phone: "+1 (963) 450-2194",
    tags: ["cupidatat", "occaecat", "amet", "qui", "elit", "esse", "deserunt"],
    friends: [
      {
        id: 0,
        name: "Loraine Harper",
      },
      {
        id: 1,
        name: "Luann Randall",
      },
      {
        id: 2,
        name: "Obrien Rich",
      },
      {
        id: 3,
        name: "Noble Wilkerson",
      },
    ],
  },
  {
    _id: "5e985a07148cfba58c860ec2",
    age: 26,
    eyeColor: "brown",
    name: "Marina Porter",
    gender: "female",
    company: "GORGANIC",
    email: "marinaporter@gorganic.com",
    phone: "+1 (867) 417-3497",
    tags: [
      "laborum",
      "aliquip",
      "sit",
      "adipisicing",
      "aute",
      "cupidatat",
      "aliquip",
    ],
    friends: [
      {
        id: 0,
        name: "Blair Hill",
      },
      {
        id: 1,
        name: "Ebony Jimenez",
      },
    ],
  },
  {
    _id: "5e985a074984f9f08ccaaa4c",
    age: 255,
    eyeColor: "green",
    name: "Barlow Ferguson",
    gender: "male",
    company: "TOYLETRY",
    email: "barlowferguson@toyletry.com",
    phone: "+1 (837) 484-2231",
    tags: ["est", "dolor", "minim", "ut", "anim", "culpa", "non"],
    friends: [
      {
        id: 0,
        name: "Delacruz Acevedo",
      },
      {
        id: 1,
        name: "Gloria Tanner",
      },
      {
        id: 2,
        name: "Cantrell Myers",
      },
      {
        id: 3,
        name: "Fisher Leonard",
      },
      {
        id: 3,
        name: "Gloria Tenner",
      },
    ],
  },
];

我想编写一个 function递归过滤所需的单词并返回包含该单词的 object。

例如: function filterWith(data, "Sheppard Jensen") 将返回

    _id: "5e985a07feddae7617ac44f6",
    age: 24,
    eyeColor: "brown",
    name: "Cummings Baxter",
    gender: "male",
    company: "VELOS",
    email: "cummingsbaxter@velos.com",
    phone: "+1 (907) 482-2451",
    tags: ["labore", "elit", "excepteur", "nisi", "mollit", "anim", "aliquip"],
    friends: [
      {
        id: 0,
        name: "Sheppard Jensen",
      },
    ],
  },

我可以非递归地执行此操作,但由于递归方式可能更有效,我想知道执行此操作的方法。 真的很感激任何帮助。

这里是一个简单的方式,因为 JSON.stringify 本身使用递归方式

function filterWith(data, str) {
    return data.filter(each => JSON.stringify(each).indexOf(str) > -1)
}

但你想自己做,你可以试试这个方法

function filterWith(data, str) {
    const isTarget = (_, str) => _.indexOf(str) > -1;
    const $filterWith = ($data) => {
        if ($data === undefined || $data === null) {
            return false;
        }
        if (typeof $data != 'object' ) {
            return isTarget(`${$data}`, `${str}`)
        }
        if (Array.isArray($data)) {
            for (let i of $data) {
                if ($filterWith($data[i])) return true
            }
        }
        for (let i in $data) {
              if (isTarget(`${data}`, `${i}`) || $filterWith($data[i])) return true
        }
        return false
    } 
    return data.filter(each => $filterWith(each))
}

我会写一个相当简单的递归检查给定的 object 是否包含字符串,然后在此之上编写一个琐碎的过滤器。

 const hasString = (str) => (obj) => Array.isArray (obj)? obj.some (hasString (str)): Object (obj) === obj? hasString (str) (Object. values (obj)): typeof obj === 'string'? obj.includes (str): false const filterWith = (xs, str) => xs.filter (hasString (str)) const input = [{_id: "5e985a07feddae7617ac44f6", age: 24, eyeColor: "brown", name: "Cummings Baxter", gender: "male", company: "VELOS", email: "cummingsbaxter@velos.com", phone: "+1 (907) 482-2451", tags: ["labore", "elit", "excepteur", "nisi", "mollit", "anim", "aliquip"], friends: [{id: 0, name: "Sheppard Jensen"}]}, {_id: "5e985a0709dfa1e6fd93c6ad", age: 32, eyeColor: "brown", name: "Madelyn Dickson", gender: "female", company: "KENGEN", email: "madelyndickson@kengen.com", phone: "+1 (984) 521-2439", tags: ["nisi", "veniam", "dolore", "officia", "ex", "non", "pariatur"], friends: [{id: 0, name: "Bruce Barton"}, {id: 1, name: "Juliet Schmidt"}, {id: 2, name: "Horton Haley"}, {id: 3, name: "Herminia Witt"}]}, {_id: "5e985a0737e2306e9aef6ecd", age: 26, eyeColor: "blue", name: "Mcguire Mercado", gender: "male", company: "LINGOAGE", email: "mcguiremercado@lingoage.com", phone: "+1 (963) 450-2194", tags: ["cupidatat", "occaecat", "amet", "qui", "elit", "esse", "deserunt"], friends: [{id: 0, name: "Loraine Harper"}, {id: 1, name: "Luann Randall"}, {id: 2, name: "Obrien Rich"}, {id: 3, name: "Noble Wilkerson"}]}, {_id: "5e985a07148cfba58c860ec2", age: 26, eyeColor: "brown", name: "Marina Porter", gender: "female", company: "GORGANIC", email: "marinaporter@gorganic.com", phone: "+1 (867) 417-3497", tags: ["laborum", "aliquip", "sit", "adipisicing", "aute", "cupidatat", "aliquip"], friends: [{id: 0, name: "Blair Hill"}, {id: 1, name: "Ebony Jimenez"}]}, {_id: "5e985a074984f9f08ccaaa4c", age: 255, eyeColor: "green", name: "Barlow Ferguson", gender: "male", company: "TOYLETRY", email: "barlowferguson@toyletry.com", phone: "+1 (837) 484-2231", tags: ["est", "dolor", "minim", "ut", "anim", "culpa", "non"], friends: [{id: 0, name: "Delacruz Acevedo"}, {id: 1, name: "Gloria Tanner"}, {id: 2, name: "Cantrell Myers"}, {id: 3, name: "Fisher Leonard"}, {id: 3, name: "Gloria Tenner"}]}] console.log (filterWith (input, 'Sheppard Jensen'))
 .as-console-wrapper {max-height: 100%;important: top: 0}

hasString检查输入是否为数组,如果是,则简单地重复其子元素,直到找到匹配项,如果不匹配则返回 false。 如果输入是 object,我们对它的键做同样的事情。 如果输入是一个字符串,我们看看它是否包含目标值。 (您可能更喜欢在这里进行相等检查。)如果它不是字符串、object 或数组,则返回 false。

filterWith是一个简单的包装器,它使用hasString过滤输入数组。

暂无
暂无

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

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