Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

213
Visualizações
filter an array of objects in javascript, with siblings that match on a common key value

Suppose I have a javascript array of objects that looks like this:

[
    {
        "title": "The Great Peace",
        "copyversion": 1
    },
    {
        "title": "History of World War II",
        "copyversion": 1
    },
    {
        "title": "Crime and Punishment",
        "copyversion": 2
    },
    {
        "title": "War and Peace",
        "copyversion": 2
    }
]

Now, suppose that I have a search string, like "War" or "and". I want to get an array of objects where "title" contains the search string (case insensitive), but I want to ALSO include any sibling values with matching "copyversion" values.

For example:

Search string of "Great" should yield the below result, because even though "History of World War II" does not have "Great" in it, it matches the copyversion of something that does.

[
    {
        "title": "The Great Peace",
        "copyversion": 1
    },
    {
        "title": "History of World War II",
        "copyversion": 1
    }
]

Another example:

Search string of "Peace" would yield the original array. "History of World War II" is included because it has the same copyversion value as "The Great Peace", and "Crime and Punishment" is included because it has the same copyversion as "War and Peace"

[
    {
        "title": "The Great Peace",
        "copyversion": 1
    },
    {
        "title": "History of World War II",
        "copyversion": 1
    },
    {
        "title": "Crime and Punishment",
        "copyversion": 2
    },
    {
        "title": "War and Peace",
        "copyversion": 2
    }
]

If no matches are found, then an empty array would result.

I'm looking for a reasonable fast way to do this. I'm fine with pure javascript or a library like lodash.

about 4 years ago · Juan Pablo Isaza
3 Respostas
Responde à pergunta

0

That is my simple and readable solution. Hope it will useful for you

const books = [
    {
        "title": "The Great Peace",
        "copyversion": 1
    },
    {
        "title": "History of World War II",
        "copyversion": 1
    },
    {
        "title": "Crime and Punishment",
        "copyversion": 2
    },
    {
        "title": "War and Peace",
        "copyversion": 2
    }
];

const findBooks = (titlePart) => {
    const regexp = new RegExp(`${titlePart}`, 'i');
    const resultSet = new Set();
    const copyVersionsSet = new Set();

    // Find all books which has titlePart in title
    for (const book of books) {
        if (regexp.test(book.title)) {
            resultSet.add(book);
            copyVersionsSet.add(book.copyversion);
        }
    }
  
    // Find all books which has same copyversion as found books
    for (const book of books) {
        if (copyVersionsSet.has(book.copyversion)) {
            resultSet.add(book);
        }
    }

    return [...resultSet];
}

console.log(findBooks('hIsToRy'));

about 4 years ago · Juan Pablo Isaza Relatório

0

Solution contains two parts:

  1. find all matching objects and collect their copyversion. Do not store duplicates.
  2. return all objects with the corresponding copyversion.

The first part may be optimized - we don't have to remove duplicates.

const a = [
    {
        "title": "The Great Peace",
        "copyversion": 1
    },
    {
        "title": "History of World War II",
        "copyversion": 1
    },
    {
        "title": "Crime and Punishment",
        "copyversion": 2
    },
    {
        "title": "War and Peace",
        "copyversion": 2
    }
];

const copyFinder = (word, arr) => {
  const rx = new RegExp(`${word}`, 'i');
  const versions = arr.reduce((collector, value) => {
    if(rx.test(value.title) && collector.indexOf(value.copyversion) === -1) {
      collector.push(value.copyversion);
    }
    return collector;
  }, []);
  if(versions.length === 0) {
    return [];
  }
  return arr.filter(x => versions.indexOf(x.copyversion) > -1);
}

console.log(copyFinder('History', a));

about 4 years ago · Juan Pablo Isaza Relatório

0

Here's one approach:

const findMatches = (books = []) => (
  search = "", 
  lc = search .toLowerCase (), 
  matches = new Set (books .filter (({title}) => title .toLowerCase () .includes (lc))),
  versions = new Set ([...matches] .map (({copyversion}) => copyversion))
) => books .filter ((book) => matches .has (book) || versions .has (book .copyversion))

const books = [{"title": "The Great Peace", "copyversion": 1}, {"title": "History of World War II", "copyversion": 1}, {"title": "Crime and Punishment", "copyversion": 2}, {"title": "War and Peace", "copyversion": 2}]

console .log ('crime: ', findMatches (books) ('crime'))
console .log ('great: ', findMatches (books) ('great'))
console .log ('war: ',   findMatches (books) ('war'))
.as-console-wrapper {max-height: 100% !important; top: 0}

We take the lower-case version of the search string, use that to filter the list to those with matching titles, storing them as a Set, then mapping them to their versions, again storing as a Set, and finally filter the original list of books to select those in that matches set or whose versions are in the version one.

Although I choose to work in this style, using defaulted parameters in place of local variables when feasible, there is a potential down-side, if findMatches (books) is used in certain ways, such as being passed to map. If that's a concern, this version does the same thing in a slightly more complex manner, without those potential problems, as the only parameters it knows about are books and search:

const findMatches = (books = []) => (search = "") => ((
  lc = search .toLowerCase (), 
  matches = new Set (books .filter (({title}) => title .toLowerCase () .includes (lc))),
  versions = new Set ([...matches] .map (({copyversion}) => copyversion))
) => books .filter ((book) => matches .has (book) || versions .has (book .copyversion)))()
about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda