最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Filter array by nested value that meets certain condition in Vue - Stack Overflow

programmeradmin2浏览0评论

I am trying to filter an Array that contains nested array of Objects. I would like for the v-for to only show those objects that meet certain condition. I have created a JSfiddle Click Here

The part that confuses me is that each enagagement could have 1 object or 3 objects, and I don't know how to check value conditions for each nested object.

I want to only show Engagements with questions that are not answered. I am using a boolean value to represent whether the question is answered or not.

This is the v-for

<div id="app">
  <h2>Engagements:</h2>
  <div>
    <div v-for="(engagment, index) in filteredQuestions" :key="index">
      <li v-for="question in engagment.questions" :key="question.id">
        <span>{{ question.id }},</span>
        <span> {{ question.question}} </span>
        <span><input type="checkbox" v-model="question.answered"></span>
      </li>
    </div>
  </div>
</div>

This is the Script and Data

new Vue({
  el: "#app",
  data: {
    engagements: [
      { 
        id: 1,
        text: "1040", 
        questions: [
            {
            id: 1,
            question: 'this is a question',
            answered: 0
          },
          {
            id: 2,
            question: 'this is a question',
            answered: 1
          },
        ]
      },
      { 
        id: 2,
        text: "1040", 
        questions: [
            {
            id: 3,
            question: 'this is a question',
            answered: 0
          },
        ]
      },
    ]
  },
  puted: {
    filteredQuestions() {
        const engagement =  this.engagements.filter((engagement) => {
            return engagement.questions.filter((question) => question.answered === 0)
        })
        return engagement
    }
  }
})

Currently no matter how I format the filteredQuestions method it will either render the entire list or show nothing. Please view the jsfiddle I included at the top of this post!

I am trying to filter an Array that contains nested array of Objects. I would like for the v-for to only show those objects that meet certain condition. I have created a JSfiddle Click Here

The part that confuses me is that each enagagement could have 1 object or 3 objects, and I don't know how to check value conditions for each nested object.

I want to only show Engagements with questions that are not answered. I am using a boolean value to represent whether the question is answered or not.

This is the v-for

<div id="app">
  <h2>Engagements:</h2>
  <div>
    <div v-for="(engagment, index) in filteredQuestions" :key="index">
      <li v-for="question in engagment.questions" :key="question.id">
        <span>{{ question.id }},</span>
        <span> {{ question.question}} </span>
        <span><input type="checkbox" v-model="question.answered"></span>
      </li>
    </div>
  </div>
</div>

This is the Script and Data

new Vue({
  el: "#app",
  data: {
    engagements: [
      { 
        id: 1,
        text: "1040", 
        questions: [
            {
            id: 1,
            question: 'this is a question',
            answered: 0
          },
          {
            id: 2,
            question: 'this is a question',
            answered: 1
          },
        ]
      },
      { 
        id: 2,
        text: "1040", 
        questions: [
            {
            id: 3,
            question: 'this is a question',
            answered: 0
          },
        ]
      },
    ]
  },
  puted: {
    filteredQuestions() {
        const engagement =  this.engagements.filter((engagement) => {
            return engagement.questions.filter((question) => question.answered === 0)
        })
        return engagement
    }
  }
})

Currently no matter how I format the filteredQuestions method it will either render the entire list or show nothing. Please view the jsfiddle I included at the top of this post!

Share Improve this question edited Sep 14, 2020 at 9:02 mkrieger1 23.5k7 gold badges64 silver badges82 bronze badges asked Oct 28, 2018 at 2:40 TJ WeemsTJ Weems 1,1143 gold badges22 silver badges39 bronze badges 2
  • Do you want all questions not answered displayed? What if an engagement have all questions answered? Keep in mind filter requires returning a boolean which is not the case for your first filter. – akuiper Commented Oct 28, 2018 at 2:45
  • @Psidom, yeah I would like for it display only questions not answered. The part about if the questions are answered for the engagement, I would idealy like to hide the engagement entirely at that point but i'm not sure how to make that happen. I was referencing other examples of filter to try and make it work so if it looks wrong at this point I would not be surprised. – TJ Weems Commented Oct 28, 2018 at 3:49
Add a ment  | 

2 Answers 2

Reset to default 6

You're filtering the engagements based on them having 1 or more unanswered questions, but the v-for is still rendering all questions inside those engagements.

WRONG: Add v-if="question.answered==0" to the <li> element to only show unanswered questions. (This is wrong practice, I found out: see lint error here. You should not use v-if and v-for on the same element.)

CORRECT: In this case extend your filteredQuestions puted value function to only return questions without answers. (Now you are just filtering the engagements based on that, but still returning all of the questions.)

Your puted value function could be:

filteredQuestions() {
    return this.engagements
        // Return a modified copy of engagements..
        .map((engagement) => {
            // ..with all answered questions filtered out..
            engagement.questions = engagement.questions.filter((question) => question.answered === 0);
            return engagement;
        })
        // ..and only return engagements that have (unanswered) questions left
        .filter((engagement) => engagement.questions.length !== 0);
}

The above option not work if you are trying to find the first level's array and nested item in array

For example engagements's name and questions sub item name because the filter will do the last match

If you are trying to find matches on nested array for example on names should do the next code

  return this.content.filter((sub) => {
      //for save the status
      let show = false
      //find in nested: themes
      sub.Themes = sub.Themes.filter((theme) => {
        if (reg.test(theme.name)) {
          show = true
          return true
        }
        return false
      })
      //if was finded match in themes show the subject or if the subject name match too
      if (show === true || reg.test(sub.name)) {
        return true
      }
      return false
    })
发布评论

评论列表(0)

  1. 暂无评论