user3041764 user3041764 - 5 months ago 7
JSON Question

Get element from array by value in Javascript

I have simple code which allows me display related product based on tags, but I would like expand that code, that can I type more than one tag. At this moment I can run only:

<script type="text/javascript">category('tag1');</script>


And I got every product with 'tag1' in their tags. In this case
name1
and
name2
.

var products = [
{
name: 'name1',
tags: ['tag1', 'tag2', 'tag3'],
},
{
name: 'name2',
tags: ['tag1', 'tag3', 'tag4', 'tag5'],
},
{
name: 'name3',
tags: ['tag2', 'tag5', 'tag6'],
}

];

var finalHtml = "";

function category(tag) {
return products.filter(function(product){
if (~product.tags.indexOf(tag)) {
finalHtml += '<li>' + product.name + '</li>';
document.getElementById("related_prod").innerHTML = finalHtml;
}
});
}


What I expect?

When I will run that code:

<script type="text/javascript">category('tag1, tag6');</script>


I would like see every product which has
tag1
OR
tag2
in their tags. In this case it should be
name1
and
name3
.

Answer

Here is a solution using ECMAScript2015:

var products = [
  {
    name: 'name1',
    tags: ['tag1', 'tag2', 'tag3'],
  },
  {
    name: 'name2',
    tags: ['tag1', 'tag3', 'tag4', 'tag5'],
  },
  {
    name: 'name3',
    tags: ['tag2', 'tag5', 'tag6'],
  }
];

function category(...tags) {
    let related = document.getElementById("related_prod");
    // clear output
    related.innerHTML = '';
    // turn array values into object properties for faster lookup
    tags = tags.reduce((tags, tag) => (tags[tag] = 1, tags), {});
    // find products that have at least one of the tags 
    products.filter(product => product.tags.some(tag => tags[tag]))
            // display the names of the found products 
            .forEach(product => {
                let li = document.createElement('li');
                li.textContent = product.name;
                related.appendChild(li);
            });
}

category('tag4','tag5');
<ul id="related_prod"></ul>