javascript - 对内部有数组的对象进行过滤

标签 javascript arrays filter

所以,在这个问题上有点挣扎。

我有一个看起来像这样的对象:

const search = something.map((some) => {
  const search = {
    writer: some.writers, // (this is an array)
    title: some.title.toLowerCase(),
    reference: some.reference.toLowerCase(),
  };
  return search;
});

我正在尝试搜索对象值内的所有文本。 some.writer 字段是一个数组,里面可以有多个 writer。

我目前正在这样过滤:

const filtered = search.filter((entry) => Object.values(entry).some((val) => typeof val === 'string'
&& val.includes(searchTerm)));

该过滤器在对象内查找搜索词并返回包含该词或部分词的所有字符串。

问题是,它只查看顶层,而不会进入 writers 数组内部进行搜索。

我怎样才能做到这一点?

最佳答案

请参阅下面的选项,您不需要 search 数组(假设您正在执行完整字符串匹配,而不是子字符串),但如果您保留 search code> 数组然后当从 something 数组构建它时,我还会将所有编写器设置为小写(并且我会在“降低”操作中使用 toLocaleLowerCase 来实现区域设置感知) :

const search = something.map((some) => {
    const entry = {
        writer: some.writers.map(writer => writer.toLocaleLowerCase()),
        title: some.title.toLocaleLowerCase(),
        reference: some.reference.toLocaleLowerCase(),
    };
    return entry;
});

然后在过滤时,我会更直接地搜索,而不是构建一堆中间数组:

// I'm assuming `val` has already been put through `toLocaleLowerCase`
const filtered = search.filter(({title, reference, writers}) => {
    return title === val || reference === val || writers.includes(val);
});

但是,如果您想使其动态化,以便在不修改搜索代码的情况下向条目添加新属性(除了创建搜索时),那么正如注释中指出的那样,您可以使用flat展平值数组,以便 writers 分散到数组的顶层:

// I'm assuming `val` has already been put through `toLocaleLowerCase`
const filtered = search.filter(entry => Object.values(entry).flat().includes(val));

两者都相当容易调整以进行子字符串搜索:

// I'm assuming `val` has already been put through `toLocaleLowerCase`
const filtered = search.filter(({title, reference, writers}) => {
    return title.includes(val) || reference.includes(val) || writers.some(writer => writer.includes(val));
});

// I'm assuming `val` has already been put through `toLocaleLowerCase`
const filtered = search.filter(entry => Object.values(entry).flat().some(e => e.includes(val)));

您可能还想使用normalize搜索值和 val 来处理某些“字符”在 Unicode 中表示的不同方式中的差异。如果是这样,基本上将上面的所有 .toLocaleLowerCase() 更改为 .normalize().toLocaleLowerCase()


如果您进行精确匹配,则可以避免创建 search 数组并执行所有这些 toLowerCase/toLocaleLowerCase 调用。这还有一个优点,即搜索结果具有原始形式的文本。为此,您可以使用 Intl.Collator对象告诉它您想要通过 sensitivity option 进行不区分大小写的匹配:

const {compare} = new Intl.Collator(undefined, {
    sensitivity: "accent" // Or you might want `"base"`
});
const match = (a, b) => compare(a, b) === 0);
const filtered = something.filter(({title, reference, writers}) => {
    return match(title, val) || match(reference, val) || writers.some(writer => match(writer, val));
});

关于javascript - 对内部有数组的对象进行过滤,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69552272/

相关文章:

使用 memcpy 将一维数组复制到一行二维数组

java - 我的二维数组平均值和中位数计算(使用 Java 中的类)有什么问题?

javascript - 为什么它给我这个错误 # Fatal error in , line 0 # Fatal JavaScript invalid size error 169220804?

php - (Wordpress) Contact Form 7 在 before_send_mail 过滤器中中止

javascript - void 函数返回值使用 JavaScript

javascript - 当用户转到另一个页面时,$rootScope.bodyClass 不会改变

python - 在 pandas groupby 之后只过滤少数组元素

python - jinja2 自定义过滤器 "TemplateAssertionError: no filter named ' format_number'"

javascript - Web应用程序使用Redux,如何处理逻辑只需要执行一次

php - 当访问者在输入文本字段中键入颜色代码时自动更改示例边框