Dynamic array filtering by object property












0















I have a react live search dropdown component that filters through an array of objects by a search term. It filters my objects by title and then returns a list of all the related objects. This works fine.



Current:



Data Structure



data: [
{ id: 1, title: 'Some title here' },
{ id: 2, title: 'Another title' },
{ id: 3, title: 'last title' },
]


Component



   <LiveSearch
term={term}
data={data} />


Inside Live search component



Filter data by term and render list



return data
.filter(item => item.title.toLowerCase().includes(term.toLowerCase())
.map((item, idx) => <li key={idx}>{item.title}</li>


My objects to search by are getting more advanced and what I would like to be able to do is pass into my component an array of property names I would like to compare to the search term.



My thinking process behind it is to loop through the object properties and if on of the properties matches the term the loop breaks and returns true adding that object to the list of items to be displayed.



Goal



Data Structure



data: [
{ id: 1, country: 'Canada', title: 'Some title here' },
{ id: 2, country: 'Australia', title: 'Another title' },
{ id: 3, country: 'Netherlands', title: 'last title' },
]


Component



<LiveSearch
searchFields={['country', 'title']}
term={term}
data={data} />


Inside Component filtering



return data
.filter(item => {
// Dynamic filtering of terms here
})
.map((item, idx) => <li key={idx}>{item.title}</li>


Inside the filter I'm trying to get a loop through the array and dynamically produce logic similar to this



item.searchFields[0].toLowerCase().includes(term.toLowerCase()) ||
item.searchFields[1].toLowerCase().includes(term.toLowerCase())


But obviously could loop over an infinite number of searchfields/properties










share|improve this question



























    0















    I have a react live search dropdown component that filters through an array of objects by a search term. It filters my objects by title and then returns a list of all the related objects. This works fine.



    Current:



    Data Structure



    data: [
    { id: 1, title: 'Some title here' },
    { id: 2, title: 'Another title' },
    { id: 3, title: 'last title' },
    ]


    Component



       <LiveSearch
    term={term}
    data={data} />


    Inside Live search component



    Filter data by term and render list



    return data
    .filter(item => item.title.toLowerCase().includes(term.toLowerCase())
    .map((item, idx) => <li key={idx}>{item.title}</li>


    My objects to search by are getting more advanced and what I would like to be able to do is pass into my component an array of property names I would like to compare to the search term.



    My thinking process behind it is to loop through the object properties and if on of the properties matches the term the loop breaks and returns true adding that object to the list of items to be displayed.



    Goal



    Data Structure



    data: [
    { id: 1, country: 'Canada', title: 'Some title here' },
    { id: 2, country: 'Australia', title: 'Another title' },
    { id: 3, country: 'Netherlands', title: 'last title' },
    ]


    Component



    <LiveSearch
    searchFields={['country', 'title']}
    term={term}
    data={data} />


    Inside Component filtering



    return data
    .filter(item => {
    // Dynamic filtering of terms here
    })
    .map((item, idx) => <li key={idx}>{item.title}</li>


    Inside the filter I'm trying to get a loop through the array and dynamically produce logic similar to this



    item.searchFields[0].toLowerCase().includes(term.toLowerCase()) ||
    item.searchFields[1].toLowerCase().includes(term.toLowerCase())


    But obviously could loop over an infinite number of searchfields/properties










    share|improve this question

























      0












      0








      0








      I have a react live search dropdown component that filters through an array of objects by a search term. It filters my objects by title and then returns a list of all the related objects. This works fine.



      Current:



      Data Structure



      data: [
      { id: 1, title: 'Some title here' },
      { id: 2, title: 'Another title' },
      { id: 3, title: 'last title' },
      ]


      Component



         <LiveSearch
      term={term}
      data={data} />


      Inside Live search component



      Filter data by term and render list



      return data
      .filter(item => item.title.toLowerCase().includes(term.toLowerCase())
      .map((item, idx) => <li key={idx}>{item.title}</li>


      My objects to search by are getting more advanced and what I would like to be able to do is pass into my component an array of property names I would like to compare to the search term.



      My thinking process behind it is to loop through the object properties and if on of the properties matches the term the loop breaks and returns true adding that object to the list of items to be displayed.



      Goal



      Data Structure



      data: [
      { id: 1, country: 'Canada', title: 'Some title here' },
      { id: 2, country: 'Australia', title: 'Another title' },
      { id: 3, country: 'Netherlands', title: 'last title' },
      ]


      Component



      <LiveSearch
      searchFields={['country', 'title']}
      term={term}
      data={data} />


      Inside Component filtering



      return data
      .filter(item => {
      // Dynamic filtering of terms here
      })
      .map((item, idx) => <li key={idx}>{item.title}</li>


      Inside the filter I'm trying to get a loop through the array and dynamically produce logic similar to this



      item.searchFields[0].toLowerCase().includes(term.toLowerCase()) ||
      item.searchFields[1].toLowerCase().includes(term.toLowerCase())


      But obviously could loop over an infinite number of searchfields/properties










      share|improve this question














      I have a react live search dropdown component that filters through an array of objects by a search term. It filters my objects by title and then returns a list of all the related objects. This works fine.



      Current:



      Data Structure



      data: [
      { id: 1, title: 'Some title here' },
      { id: 2, title: 'Another title' },
      { id: 3, title: 'last title' },
      ]


      Component



         <LiveSearch
      term={term}
      data={data} />


      Inside Live search component



      Filter data by term and render list



      return data
      .filter(item => item.title.toLowerCase().includes(term.toLowerCase())
      .map((item, idx) => <li key={idx}>{item.title}</li>


      My objects to search by are getting more advanced and what I would like to be able to do is pass into my component an array of property names I would like to compare to the search term.



      My thinking process behind it is to loop through the object properties and if on of the properties matches the term the loop breaks and returns true adding that object to the list of items to be displayed.



      Goal



      Data Structure



      data: [
      { id: 1, country: 'Canada', title: 'Some title here' },
      { id: 2, country: 'Australia', title: 'Another title' },
      { id: 3, country: 'Netherlands', title: 'last title' },
      ]


      Component



      <LiveSearch
      searchFields={['country', 'title']}
      term={term}
      data={data} />


      Inside Component filtering



      return data
      .filter(item => {
      // Dynamic filtering of terms here
      })
      .map((item, idx) => <li key={idx}>{item.title}</li>


      Inside the filter I'm trying to get a loop through the array and dynamically produce logic similar to this



      item.searchFields[0].toLowerCase().includes(term.toLowerCase()) ||
      item.searchFields[1].toLowerCase().includes(term.toLowerCase())


      But obviously could loop over an infinite number of searchfields/properties







      javascript arrays filter






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 14 '18 at 17:36









      Jason McFarlaneJason McFarlane

      459210




      459210
























          3 Answers
          3






          active

          oldest

          votes


















          1














          Use Array#some()



          Something like



          term = term.toLowerCase()
          return data
          .filter(item => {
          return searchFields.some(field => item[field].toLowerCase().includes(term))
          }).map(...





          share|improve this answer

































            1














            Check if some of the searchFields match:



            // Checks wether a value matches a term
            const matches = (value, term) => value.toLowerCase().includes(term.toLowerCase());

            // Checks wether one of the fields in the item matcues the term
            const itemMatches = (fields, term) => item => fields.some(field => matches(item[field], term);

            // Filter the data to only contain items where on of the searchFields matches the term
            const result = props.data.filter( itemMatches(props.searchFields, props.term) );

            return result.map(item => <li key={idx}>{item.title}</li>);





            share|improve this answer































              1














              You can use Array .some combined with .filter



              let result = data.filter(obj => 
              searchFields.some(s =>
              obj[s] != undefined && obj[s].toLowerCase() === term
              ));





              let data = [
              { id: 1, country: 'Canada', title: 'Some title here' },
              { id: 2, country: 'Australia', title: 'Another title' },
              { id: 3, country: 'Netherlands', title: 'last title' },
              ], searchFields = ["country", "title"], term = "canada";

              let result = data.filter(obj =>
              searchFields.some(s =>
              obj[s] != undefined && obj[s].toLowerCase() === term
              ));

              console.log(result);








              share|improve this answer


























              • That is really overcomplicating things.

                – Jonas Wilms
                Nov 14 '18 at 17:49











              • @JonasWilms Possibly? That's not really a constructive comment. Care to elaborate?

                – zfrisch
                Nov 14 '18 at 17:55











              • That flag ? I mean you always check all the properties, you could actually exit after the first found.

                – Jonas Wilms
                Nov 14 '18 at 17:56











              • @JonasWilms good point. Better?

                – zfrisch
                Nov 14 '18 at 18:03











              Your Answer






              StackExchange.ifUsing("editor", function () {
              StackExchange.using("externalEditor", function () {
              StackExchange.using("snippets", function () {
              StackExchange.snippets.init();
              });
              });
              }, "code-snippets");

              StackExchange.ready(function() {
              var channelOptions = {
              tags: "".split(" "),
              id: "1"
              };
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function() {
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled) {
              StackExchange.using("snippets", function() {
              createEditor();
              });
              }
              else {
              createEditor();
              }
              });

              function createEditor() {
              StackExchange.prepareEditor({
              heartbeatType: 'answer',
              autoActivateHeartbeat: false,
              convertImagesToLinks: true,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: 10,
              bindNavPrevention: true,
              postfix: "",
              imageUploader: {
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              },
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              });


              }
              });














              draft saved

              draft discarded


















              StackExchange.ready(
              function () {
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53305885%2fdynamic-array-filtering-by-object-property%23new-answer', 'question_page');
              }
              );

              Post as a guest















              Required, but never shown

























              3 Answers
              3






              active

              oldest

              votes








              3 Answers
              3






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              1














              Use Array#some()



              Something like



              term = term.toLowerCase()
              return data
              .filter(item => {
              return searchFields.some(field => item[field].toLowerCase().includes(term))
              }).map(...





              share|improve this answer






























                1














                Use Array#some()



                Something like



                term = term.toLowerCase()
                return data
                .filter(item => {
                return searchFields.some(field => item[field].toLowerCase().includes(term))
                }).map(...





                share|improve this answer




























                  1












                  1








                  1







                  Use Array#some()



                  Something like



                  term = term.toLowerCase()
                  return data
                  .filter(item => {
                  return searchFields.some(field => item[field].toLowerCase().includes(term))
                  }).map(...





                  share|improve this answer















                  Use Array#some()



                  Something like



                  term = term.toLowerCase()
                  return data
                  .filter(item => {
                  return searchFields.some(field => item[field].toLowerCase().includes(term))
                  }).map(...






                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Nov 14 '18 at 17:46

























                  answered Nov 14 '18 at 17:41









                  charlietflcharlietfl

                  139k1389122




                  139k1389122

























                      1














                      Check if some of the searchFields match:



                      // Checks wether a value matches a term
                      const matches = (value, term) => value.toLowerCase().includes(term.toLowerCase());

                      // Checks wether one of the fields in the item matcues the term
                      const itemMatches = (fields, term) => item => fields.some(field => matches(item[field], term);

                      // Filter the data to only contain items where on of the searchFields matches the term
                      const result = props.data.filter( itemMatches(props.searchFields, props.term) );

                      return result.map(item => <li key={idx}>{item.title}</li>);





                      share|improve this answer




























                        1














                        Check if some of the searchFields match:



                        // Checks wether a value matches a term
                        const matches = (value, term) => value.toLowerCase().includes(term.toLowerCase());

                        // Checks wether one of the fields in the item matcues the term
                        const itemMatches = (fields, term) => item => fields.some(field => matches(item[field], term);

                        // Filter the data to only contain items where on of the searchFields matches the term
                        const result = props.data.filter( itemMatches(props.searchFields, props.term) );

                        return result.map(item => <li key={idx}>{item.title}</li>);





                        share|improve this answer


























                          1












                          1








                          1







                          Check if some of the searchFields match:



                          // Checks wether a value matches a term
                          const matches = (value, term) => value.toLowerCase().includes(term.toLowerCase());

                          // Checks wether one of the fields in the item matcues the term
                          const itemMatches = (fields, term) => item => fields.some(field => matches(item[field], term);

                          // Filter the data to only contain items where on of the searchFields matches the term
                          const result = props.data.filter( itemMatches(props.searchFields, props.term) );

                          return result.map(item => <li key={idx}>{item.title}</li>);





                          share|improve this answer













                          Check if some of the searchFields match:



                          // Checks wether a value matches a term
                          const matches = (value, term) => value.toLowerCase().includes(term.toLowerCase());

                          // Checks wether one of the fields in the item matcues the term
                          const itemMatches = (fields, term) => item => fields.some(field => matches(item[field], term);

                          // Filter the data to only contain items where on of the searchFields matches the term
                          const result = props.data.filter( itemMatches(props.searchFields, props.term) );

                          return result.map(item => <li key={idx}>{item.title}</li>);






                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered Nov 14 '18 at 17:43









                          Jonas WilmsJonas Wilms

                          58.4k43151




                          58.4k43151























                              1














                              You can use Array .some combined with .filter



                              let result = data.filter(obj => 
                              searchFields.some(s =>
                              obj[s] != undefined && obj[s].toLowerCase() === term
                              ));





                              let data = [
                              { id: 1, country: 'Canada', title: 'Some title here' },
                              { id: 2, country: 'Australia', title: 'Another title' },
                              { id: 3, country: 'Netherlands', title: 'last title' },
                              ], searchFields = ["country", "title"], term = "canada";

                              let result = data.filter(obj =>
                              searchFields.some(s =>
                              obj[s] != undefined && obj[s].toLowerCase() === term
                              ));

                              console.log(result);








                              share|improve this answer


























                              • That is really overcomplicating things.

                                – Jonas Wilms
                                Nov 14 '18 at 17:49











                              • @JonasWilms Possibly? That's not really a constructive comment. Care to elaborate?

                                – zfrisch
                                Nov 14 '18 at 17:55











                              • That flag ? I mean you always check all the properties, you could actually exit after the first found.

                                – Jonas Wilms
                                Nov 14 '18 at 17:56











                              • @JonasWilms good point. Better?

                                – zfrisch
                                Nov 14 '18 at 18:03
















                              1














                              You can use Array .some combined with .filter



                              let result = data.filter(obj => 
                              searchFields.some(s =>
                              obj[s] != undefined && obj[s].toLowerCase() === term
                              ));





                              let data = [
                              { id: 1, country: 'Canada', title: 'Some title here' },
                              { id: 2, country: 'Australia', title: 'Another title' },
                              { id: 3, country: 'Netherlands', title: 'last title' },
                              ], searchFields = ["country", "title"], term = "canada";

                              let result = data.filter(obj =>
                              searchFields.some(s =>
                              obj[s] != undefined && obj[s].toLowerCase() === term
                              ));

                              console.log(result);








                              share|improve this answer


























                              • That is really overcomplicating things.

                                – Jonas Wilms
                                Nov 14 '18 at 17:49











                              • @JonasWilms Possibly? That's not really a constructive comment. Care to elaborate?

                                – zfrisch
                                Nov 14 '18 at 17:55











                              • That flag ? I mean you always check all the properties, you could actually exit after the first found.

                                – Jonas Wilms
                                Nov 14 '18 at 17:56











                              • @JonasWilms good point. Better?

                                – zfrisch
                                Nov 14 '18 at 18:03














                              1












                              1








                              1







                              You can use Array .some combined with .filter



                              let result = data.filter(obj => 
                              searchFields.some(s =>
                              obj[s] != undefined && obj[s].toLowerCase() === term
                              ));





                              let data = [
                              { id: 1, country: 'Canada', title: 'Some title here' },
                              { id: 2, country: 'Australia', title: 'Another title' },
                              { id: 3, country: 'Netherlands', title: 'last title' },
                              ], searchFields = ["country", "title"], term = "canada";

                              let result = data.filter(obj =>
                              searchFields.some(s =>
                              obj[s] != undefined && obj[s].toLowerCase() === term
                              ));

                              console.log(result);








                              share|improve this answer















                              You can use Array .some combined with .filter



                              let result = data.filter(obj => 
                              searchFields.some(s =>
                              obj[s] != undefined && obj[s].toLowerCase() === term
                              ));





                              let data = [
                              { id: 1, country: 'Canada', title: 'Some title here' },
                              { id: 2, country: 'Australia', title: 'Another title' },
                              { id: 3, country: 'Netherlands', title: 'last title' },
                              ], searchFields = ["country", "title"], term = "canada";

                              let result = data.filter(obj =>
                              searchFields.some(s =>
                              obj[s] != undefined && obj[s].toLowerCase() === term
                              ));

                              console.log(result);








                              let data = [
                              { id: 1, country: 'Canada', title: 'Some title here' },
                              { id: 2, country: 'Australia', title: 'Another title' },
                              { id: 3, country: 'Netherlands', title: 'last title' },
                              ], searchFields = ["country", "title"], term = "canada";

                              let result = data.filter(obj =>
                              searchFields.some(s =>
                              obj[s] != undefined && obj[s].toLowerCase() === term
                              ));

                              console.log(result);





                              let data = [
                              { id: 1, country: 'Canada', title: 'Some title here' },
                              { id: 2, country: 'Australia', title: 'Another title' },
                              { id: 3, country: 'Netherlands', title: 'last title' },
                              ], searchFields = ["country", "title"], term = "canada";

                              let result = data.filter(obj =>
                              searchFields.some(s =>
                              obj[s] != undefined && obj[s].toLowerCase() === term
                              ));

                              console.log(result);






                              share|improve this answer














                              share|improve this answer



                              share|improve this answer








                              edited Nov 14 '18 at 18:02

























                              answered Nov 14 '18 at 17:46









                              zfrischzfrisch

                              4,55511024




                              4,55511024













                              • That is really overcomplicating things.

                                – Jonas Wilms
                                Nov 14 '18 at 17:49











                              • @JonasWilms Possibly? That's not really a constructive comment. Care to elaborate?

                                – zfrisch
                                Nov 14 '18 at 17:55











                              • That flag ? I mean you always check all the properties, you could actually exit after the first found.

                                – Jonas Wilms
                                Nov 14 '18 at 17:56











                              • @JonasWilms good point. Better?

                                – zfrisch
                                Nov 14 '18 at 18:03



















                              • That is really overcomplicating things.

                                – Jonas Wilms
                                Nov 14 '18 at 17:49











                              • @JonasWilms Possibly? That's not really a constructive comment. Care to elaborate?

                                – zfrisch
                                Nov 14 '18 at 17:55











                              • That flag ? I mean you always check all the properties, you could actually exit after the first found.

                                – Jonas Wilms
                                Nov 14 '18 at 17:56











                              • @JonasWilms good point. Better?

                                – zfrisch
                                Nov 14 '18 at 18:03

















                              That is really overcomplicating things.

                              – Jonas Wilms
                              Nov 14 '18 at 17:49





                              That is really overcomplicating things.

                              – Jonas Wilms
                              Nov 14 '18 at 17:49













                              @JonasWilms Possibly? That's not really a constructive comment. Care to elaborate?

                              – zfrisch
                              Nov 14 '18 at 17:55





                              @JonasWilms Possibly? That's not really a constructive comment. Care to elaborate?

                              – zfrisch
                              Nov 14 '18 at 17:55













                              That flag ? I mean you always check all the properties, you could actually exit after the first found.

                              – Jonas Wilms
                              Nov 14 '18 at 17:56





                              That flag ? I mean you always check all the properties, you could actually exit after the first found.

                              – Jonas Wilms
                              Nov 14 '18 at 17:56













                              @JonasWilms good point. Better?

                              – zfrisch
                              Nov 14 '18 at 18:03





                              @JonasWilms good point. Better?

                              – zfrisch
                              Nov 14 '18 at 18:03


















                              draft saved

                              draft discarded




















































                              Thanks for contributing an answer to Stack Overflow!


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid



                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.


                              To learn more, see our tips on writing great answers.




                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function () {
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53305885%2fdynamic-array-filtering-by-object-property%23new-answer', 'question_page');
                              }
                              );

                              Post as a guest















                              Required, but never shown





















































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown

































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown







                              Popular posts from this blog

                              Bressuire

                              Vorschmack

                              Quarantine