为了账号安全,请及时绑定邮箱和手机立即绑定

按两个字段对计算对象和数组进行排序

按两个字段对计算对象和数组进行排序

千万里不及你 2023-11-02 22:51:32
我从 API 中提取信息,该 API 返回以下格式的数据:[ {  "id": 173,  "date": "2020-12-10T16:05:30",  "date_gmt": "2020-12-10T16:05:30",  "guid": {},  "modified": "2020-12-10T16:05:31",  "modified_gmt": "2020-12-10T16:05:31",  "slug": "test",  "status": "publish",  "type": "place",  "link": "http://localhost:81/test/",  "title": {},  "content": {},  "featured_media": 0,  "template": "",  "acf": {    "address": {    "address": "123 Test Address",    "street_number": "123",    "street_name": "Test Address",    "city": "Philipsburg",    "state": "Sint Maarten",    "country": "Sint Maarten",    "country_short": "SX"  },  "header": {}  },  "_links": {} }, etc]我将其存储在 Vuex 中,并通过以下方式组织信息:computed: {    resorts() {      const resorts = {};      if (this.$store.state.loading === false) {        this.$store.state.posts.forEach((post) => {          const c = post.acf.address.country;          const s = post.acf.address.state;          //const t = post.title;          resorts[c] = resorts[c] || {};          resorts[c][s] = resorts[c][s] || [];          resorts[c][s].push(post);        });      }      return resorts;    },}v-for我在这样的循环中显示信息(Pug):section.united-states(v-for="(country, index) in resorts" v-if="index==='United States'")  h1(v-html="index")  section.state(v-for="(state, subIndex) in country" :key="subIndex" :class="subIndex.toLowerCase()")    h5(v-html="subIndex")    ul      li(v-for="post, resort) in state")        listing(:id="post.id" :slug="post.slug" :image="post.acf.header" :title="post.title.rendered" :city="post.acf.address.city" :street="post.acf.address.street_name_short")这样可以正确显示信息。但是,我需要它按Country、State、City名称的字母顺序排列。我尝试对其进行排序并尝试lodash.orderBy,但无法组织列表。从 Chrome 中的 Vue 检查器选项卡中,计算出的国家和州(不是城市)似乎是按字母顺序排列的。有什么建议么?
查看完整描述

1 回答

?
慕容708150

TA贡献1831条经验 获得超4个赞

一种解决方案是先对帖子进行排序,然后再按地址进行分组。

使用Array.prototype.sort()String.prototype.localeCompare(),创建一个实用程序(名为sortPosts())以在计算的 prop 中使用,该实用程序将按countrystatecity, thenstreet_name字段对帖子进行排序:

const sortPosts = posts =>

  posts.slice().sort((a,b) => {

    const countryA = a.acf.address.country

    const countryB = b.acf.address.country

    const stateA = a.acf.address.state

    const stateB = b.acf.address.state

    const cityA = a.acf.address.city || '' // can be undefined in Google Maps API

    const cityB = b.acf.address.city || '' // can be undefined in Google Maps API

    const streetA = a.acf.address.street_name

    const streetB = b.acf.address.street_name

    return countryA.localeCompare(countryB) || stateA.localeCompare(stateB) || cityA.localeCompare(cityB) || streetA.localeCompare(streetB)

  })

现在,我们将使用您已有的相同逻辑对这些帖子进行分组,但我们必须将局部resorts变量的数据类型从更改ObjectMap,因为Object迭代并不总是遵循插入顺序,这会破坏排序sortPosts()


export default {

  computed: {

    resorts() {

      // BEFORE:

      // const resorts = {};


      const resorts = new Map();


      if (this.$store.state.loading === false) {

        sortPosts(this.$store.state.posts).forEach((post) => {

          const c = post.acf.address.country;

          const s = post.acf.address.state;


          // BEFORE:

          // resorts[c] = resorts[c] || {};

          // resorts[c][s] = resorts[c][s] || [];

          // resorts[c][s].push(post);


          if (!resorts.has(c)) {

            resorts.set(c, new Map());

          }

          const stateMap = resorts.get(c);

          if (!stateMap.has(s)) {

            stateMap.set(s, []);

          }

          stateMap.get(s).push(post);

        });

      }

      return resorts

    },

  }

}

从 v2.6.12 开始,v-for不支持Maps,因此使用Array.from()使其可迭代v-for


<section v-for="[country, countryData] in Array.from(resorts)" :key="country">

  <h1 v-html="country" />

  <section class="state" v-for="[state, posts] in Array.from(countryData)" :key="state" :class="state.toLowerCase()">

    <h5 v-html="state" />

    <ul>

      <li v-for="(post, resort) in posts" :key="post.id">

        ...

      </li>

    </ul>

  </section>

</section>

演示


查看完整回答
反对 回复 2023-11-02
  • 1 回答
  • 0 关注
  • 92 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信