Searching for items within an array whose inner array contains certain objects can be achieved using lodash

I have arrays containing tasks and tags:

const tasks = [
  {id: 0, name: 'a', tags: [{id: 0, name: 'q'}, {id: 7, name: 'i'}]},
  {id: 1, name: 'b', tags: [{id: 2, name: 'e'}, {id: 4, name: 't'}, {id: 2, name: 'e'}, {id: 0, name: 'q'}]},
  {id: 2, name: 'c', tags: []},
  {id: 3, name: 'd', tags: [{id: 7, name: 'i'}, {id: 3, name: 'r'}, {id: 0, name: 'q'}]},
  {id: 6, name: 'g', tags: [{id: 7, name: 'i'}, {id: 4, name: 't'}]},
]

const tags = [
  {id: 0, name: 'q'},
  {id: 1, name: 'w'},
  {id: 2, name: 'e'},
  {id: 3, name: 'r'},
  {id: 4, name: 't'},
  {id: 7, name: 'i'},
  {id: 11, name: 's'}
]

let selectedTags = [0, 5]

The challenge is to find tasks that include all of the selected tags based on their indexes in the tags array.

Expected output:

let result = [
  {id: 0, name: 'a', tags: [{id: 0, name: 'q'}, {id: 7, name: 'i'}]},
  {id: 3, name: 'd', tags: [{id: 7, name: 'i'}, {id: 3, name: 'r'}, {id: 0, name: 'q'}]}
]

An attempted solution using lodash:

let result= []
_.forEach(selectedTags, index => {
  const tagId = tags[index]._id
  result = _.filter(tasks, task => _.find(task.tags, ['_id', tagId]))
})

However, this approach did not fulfill the criteria as it only retrieved objects with one selected tag. Any suggestions?

Answer №1

To convert your selectedTags into an array of tags, one approach is to map them.

Then, utilize the every method to confirm that every element in selectedTags is present in the tasks.tags array using some.

Check out the example below for a demonstration:

const tasks = JSON.parse('[{"id":0,"name":"a","tags":[{"id":0,"name":"q"},{"id":7,"name":"i"}]},{"id":1,"name":"b","tags":[{"id":2,"name":"e"},{"id":4,"name":"t"},{"id":2,"name":"e"},{"id":0,"name":"q"}]},{"id":2,"name":"c","tags":[]},{"id":3,"name":"d","tags":[{"id":7,"name":"i"},{"id":3,"name":"r"},{"id":0,"name":"q"}]},{"id":6,"name":"g","tags":[{"id":7,"name":"i"},{"id":4,"name":"t"}]}]');
const tags = JSON.parse('[{"id":0,"name":"q"},{"id":1,"name":"w"},{"id":2,"name":"e"},{"id":3,"name":"r"},{"id":4,"name":"t"},{"id":7,"name":"i"},{"id":11,"name":"s"}]');
let selectedTags = [0, 5];


const result = tasks.filter(f =>
  selectedTags.map(m => tags[m]).every(
    e => f.tags.some(s => s.id === e.id)));

console.log(result);

Note: If performance is a concern, you can separate the map operation.

Answer №2

You can achieve the desired outcome by utilizing the reduce method and verifying if each element contains the specified tags during each iteration:

const selectedTags = [0, 5];
const tagsToFind = selectedTags.map(tagIndex => tags[tagIndex]);

const result = tasks.reduce((accumulator, currentTask) => {
    if (tagsToFind.every(tag => currentTask.tags.some(taskTag => taskTag.name === tag.name))) {
        accumulator.push(currentTask);
    }
    return accumulator;
}, []);

Here is an illustrative example:

const tasks = [
    {id: 0, name: 'a', tags: [{id: 0, name: 'q'}, {id: 7, name: 'i'}]},
    {id: 1, name: 'b', tags: [{id: 2, name: 'e'}, {id: 4, name: 't'}, 
        {id: 2, name: 'e'}, {id: 0, name: 'q'}]},
    {id: 2, name: 'c', tags: []},
    {id: 3, name: 'd', tags: [{id: 7, name: 'i'}, {id: 3, name: 'r'}, 
        {id: 0, name: 'q'}]},
    {id: 6, name: 'g', tags: [{id: 7, name: 'i'}, {id: 4, name: 't'}]},
];

const tags = [
    {id: 0, name: 'q'},
    {id: 1, name: 'w'},
    {id: 2, name: 'e'},
    {id: 3, name: 'r'},
    {id: 4, name: 't'},
    {id: 7, name: 'i'},
    {id: 11, name: 's'}
];

let selectedTags = [0, 5];
const tagsToFind = selectedTags.map(tagIndex => tags[tagIndex]);

const result = tasks.reduce((accumulator, currentTask) => {
    if (tagsToFind.every(tag => currentTask.tags.some(taskTag => taskTag.name === tag.name))) {
        accumulator.push(currentTask);
    }
    return accumulator;
}, []);

console.log(result);

Answer №3

Begin by constructing the variable names using selectedTags and then implement the filter function on tasks.

const filter = (tasks, tags, selectedTags) => {
  const names = selectedTags.map(tag => tags[tag].name);
  return tasks.filter(task =>
    names.every(name => task.tags.map(x => x.name).includes(name))
  );
};

const tasks = [
  {
    id: 0,
    name: "a",
    tags: [
      { id: 0, name: "q" },
      { id: 7, name: "i" }
    ]
  },
  {
    id: 1,
    name: "b",
    tags: [
      { id: 2, name: "e" },
      { id: 4, name: "t" },
      { id: 2, name: "e" },
      { id: 0, name: "q" }
    ]
  },
  { id: 2, name: "c", tags: [] },
  {
    id: 3,
    name: "d",
    tags: [
      { id: 7, name: "i" },
      { id: 3, name: "r" },
      { id: 0, name: "q" }
    ]
  },
  {
    id: 6,
    name: "g",
    tags: [
      { id: 7, name: "i" },
      { id: 4, name: "t" }
    ]
  }
];

const tags = [
  { id: 0, name: "q" },
  { id: 1, name: "w" },
  { id: 2, name: "e" },
  { id: 3, name: "r" },
  { id: 4, name: "t" },
  { id: 7, name: "i" },
  { id: 11, name: "s" }
];

let selectedTags = [0, 5];

console.log(filter(tasks, tags, selectedTags));

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Getting the Right Value: A Step-by-Step Guide to Setting the Default or Selected Value in

When creating directive form controls (text, select, radio), I am passing a value to the directive function. If this value is not set or empty, then the default value should be taken from the question data._pageAttributes.defaultValue. HTML <div ng-re ...

Encountering a TypeError while trying to import grapesjs into a nextjs project, specifically receiving the error: "Cannot read properties of null (reading 'querySelector')

I encountered an issue while trying to integrate grapesjs into a nextjs project. The error I received was TypeError: Cannot read properties of null (reading 'querySelector') It appears that grapesjs is looking for the "#gjs" container by its id ...

choose and execute operations on words within an array

I'm trying to figure out a way to underline specific words from an array based on a condition in my code. The challenge is that I can only access the index as a variable, so I need to somehow convert it into an element and then apply the underline sty ...

node.js experiencing crashing following loop iteration

I'm currently developing a performance testing tool using node.js to automate the process and store the results in MySQL. This tool is designed to track the load time of specific web pages in a browser, with the measurement displayed in seconds. I am ...

What are some ways to track the loading progress of a JSON file retrieved through an Axios call?

To track progress accurately, I am contemplating implementing the following steps while making an axios call: Retrieve file size during the json file request Determine the percentage of downloaded file size from the network tab Currently, I only have a ...

Error in JavaScript Slideshow

I am attempting to create a slider that changes with a button click. Below is my JavaScript code: var img1=document.getElementById("p1"); var img2=document.getElementById("p2"); var img3=document.getElementById("p3"); function slide(){ ...

The collapsed button on the Bootstrap 4 accordion flickers slightly as it expands, not reaching its full expansion

I'm currently working on implementing an accordion feature. I found inspiration from this component here on fiddle which utilizes bootstrap 4. While attempting to troubleshoot a bug in the SO forum, I noticed that on my page, the component seems to "b ...

Nuxt.js has exceeded the maximum call stack size

Recently, I started working on a nuxt.js/vue project using a pre-built starter template. However, I have been encountering numerous error messages such as "Maximum call stack size exceeded." It's quite challenging to pinpoint the exact source of these ...

Hiding and displaying DIVs on a single HTML page using VueJs 2

I am currently working on building an application that is not a single page application. As I develop my project, I have several div elements on the page that I want to toggle visibility step by step. Below is the snippet of my code: <div v-if="sect ...

What's the fastest method for storing an array onto the disk in PHP?

Is there a simple method for saving an array to disk and then retrieving it back as an array? ...

Discover the steps to linking a dropdown menu to a text input using HTML and JavaScript

I'm currently using Sublime and trying to link a dropdown menu with an input text using html, css, and javascript. When the user selects an option from the dropdown menu, I want the corresponding value to appear in the text input field. For example, i ...

Forward after asynchronous JavaScript and XML (AJAX)

Currently, I am working on an MVC project where I need to achieve the following: The scenario involves sending an ajax request from a JS script and then redirecting to a page along with a model once the request is processed. I attempted to send a form as ...

Parsing the contents of a text file and storing them as an

I am looking to convert a text file into an array, here is a sample of the content in the text file code 1 #Updated 12/15/2000 { Reezena of Confinement } code 2 #Added in v2.0 { Neil } code 3 #Added in V1.0 { Jansen } code 4 #Updated 12/15/2000 { Gellos } ...

Exploring ways to utilize array.find by comparing it to a different object

There are two arrays in JavaScript named designs and articles. var designs = [ { design_id:"bwbmbqlujurv", article_id:14782, name:"adidas demogorgon black" }, { design_id:"lg9yba2gkcwr", article_id:14782, name:"harry potter w ...

Adjust the width of a container as its children expand

My current project involves creating a dynamic gallery using JavaScript and jQuery, where full-sized images slide out from the right side. I have successfully implemented this functionality, but now I am facing a new challenge. I need the parent block of t ...

Exploring the concept of using variables and understanding variable scope in AJAX and JavaScript

Struggling with using variables in AJAX. Attempting to have var x store data from var data but it keeps showing as undefined in the console log. Any tips on how to fix this issue? EDIT: The variable x needs to be accessed later in the code, not just for ...

Search for the value of the Array Class Object - If it is found: Reassign it as the first key

I am searching for a PHP function that can locate the value 'FIND_ME' in an array of class objects and move it to be the first key if it exists. This is the current output of my Array : Array ( [0] => stdClass Object ([id] => 1 [ ...

Pause rendering of Three.js when the video texture needs to be updated

I attempted to apply a video as a texture on a mesh, and tried two different examples: and Both examples worked fine online but didn't display anything when downloaded from GitHub. When I added the code: videoTexture.needsUpdate = false; the floo ...

Ways to dynamically eliminate focus around text inputs

I have created an HTML page and here is the link to it: https://i.sstatic.net/n8UdU.png My main goal is to remove the black border around the text input on this page. The challenge I am facing is that the 'things to do' list is generated dynamic ...

Accessing values from a multi-layered array in PHP

Hey there, I'm attempting to retrieve the fulltext values from a JSON file located at this Link. Currently, I'm only able to access the top level of the array. How can I extract all values from all arrays, including nested ones? $json_output = ...