使用分层.reduce()或.filter()函数在对象中,基于单独的搜索数组中的对象



i具有由构造函数函数创建的一系列对象。这些对象具有比此示例更多的键值对。但这一切都很好,因此无关紧要。让我们尝试保持简洁:)

示例数组:

let contactsArr = [
  {id: 1, firstName: "Lucas", email: "lucas@fake.com"},
  {id: 2, firstName: "Adrian", email: "adrian@fake.com"},
  {id: 3, firstName: "Betrand", email: "zorro@fake.com"}
  }
];

在HTML中,我有一个搜索字段#search。你凝视着它。此字段旨在搜索联系对象的数组以获取任何匹配值。

该字段的内容被修剪为一系列字符串,除以(1个矿石)空间。

const $input = $("#search").val().toLowerCase().trim().split(/[s]+/);

那里没问题。对于下一步,我想查找并返回contactsArr中对象的任何值等于(或包含)$input的字符串的任何值。第一个版本,我想出了此代码:

const filteredArr = contactsArr.filter(contact => {
            return contact.firstName.toLowerCase().includes($input) ||
                contact.email.toLowerCase().includes($input) ||
                ... // and more key-value pairs to check
        });

$input返回字符串或仅1个字符串的数组时,

工作正常。如果数组包含更多的字符串,则仅搜索第一个字符串的结果并返回。但是,考虑到将来可能会有更多的键值对,这也有些混乱。因此版本2

const filteredArr = contactsArr.filter(contact => {
            return Object.values(contact).some(x => {
                if (typeof x === "number") x = x.toString();
                return x.toLowerCase().includes($input);
            });
        });

版本2返回与版本1相同的结果,仅适用于代码中列出的键值对比较多的键值对。伟大的!!但是,当$input数组的1个值更高时,第二个值仍然被忽略。经过很多轨道和错误,我希望有人可以指出我的错误。

这是版本3 :(甚至33):)

const filteredArr = contactsArr.filter(contact => {
            return Object.values(contact).some(x => {
                // contact.id number to string
                if (typeof x === "number") x = x.toString();
                // match with lowercase (same as $input)
                x = x.toLocaleLowerCase();
                // check if includes and return true or false
                return $input.some(word => x.includes(word));
            });
        });

预期结果:目的是使所有与$input中的字符串匹配的联系人。

非常感谢所有和所有技巧和见解!

我过去所做的是通过将所有值连接在一起来创建一个大 index 字符串。然后,您可以在$input数组上使用Array.prototype.some()

let contactsArr = [
  {id: 1, firstName: "Lucas", email: "lucas@fake.com"},
  {id: 2, firstName: "Adrian", email: "adrian@fake.com"},
  {id: 3, firstName: "Betrand", email: "zorro@fake.com"}
];
let searchVal = 'lu rian'
const $input = searchVal.toLowerCase().trim().split(/s+/);
const filteredArr = contactsArr.filter(contact => {
  // create an index string by joining all the values
  const indexString = Object.values(contact).join(' ').toLowerCase()
  
  // now you can perform a single search operation
  return $input.some(word => indexString.includes(word))
})
console.info(filteredArr)

最新更新