Purple awn
Purple awn

Reputation: 137

How to customize sort objects by property?

Starting with a given array of objects, I group those by their classification property into an object keyed by that classification. Then I print out the desired classification effect.

Now I need to sort these classifications. I want the commonly used ones to be printed first, and other classifications to be sorted alphabetically after it.

So I hope the sorting effect is as follows:

  1. common used is the first
  2. others are alphabetic

Here is the expected structure, the actual results in the code run


commonly-used

movie-type

search-type

study-type

tool-type


Here is my code where the grouping is done, but where I still need to add the sorting somehow:

let ary = [{
  "type": "search-type",
  "content": {
    "title": "google",
    "link": "https://",
  }
}, {
  "type": "study-type",
  "content": {
    "title": "w3c",
    "link": "https://",
  }
}, {
  "type": "movie-type",
  "content": {
    "title": "movie site",
    "link": "https://",
  }
}, {
  "type": "commonly-used",
  "content": {
    "title": "stackoverflow",
    "link": "https://",
  }
}, {
  "type": "tool-type",
  "content": {
    "title": "remove bg",
    "link": "https://www//",
  }
}, {
  "type": "movie-type",
  "content": {
    "title": "movie site2",
    "link": "https://",
  }
}, {
  "type": "commonly-used",
  "content": {
    "title": "github",
    "link": "https://",
  }
}, {
  "type": "search-type",
  "content": {
    "title": "wikipedia",
    "link": "https://xx",
  }
}, {
  "type": "study-type",
  "content": {
    "title": "vue",
    "link": "https://",
  }
}, {
  "type": "study-type",
  "content": {
    "title": "react",
    "link": "https://",
  }
}];

////////////////////
let tempJson = {};

ary.forEach(data => tempJson[data.type] = [])

ary.forEach(data => {
  for (const key in tempJson) {
    if (data.type === key) {
      tempJson[key].push(data.content);
      break;
    }
  }
})

for (const classification in tempJson) {
  const wrapNode = `<div class="item-wrap">
    <h3>${classification}</h3>
    ${(() => {
      let contentWrapNode = ``;
      tempJson[classification].forEach(item => {
        const itemNode = `<div class="items"><a href="${item.link}">${item.title}</a></div>`;
        contentWrapNode += itemNode;
      })
      return contentWrapNode;
    })()}
  </div>`;

  document.querySelector('.container').innerHTML += wrapNode;
}
<div class="container"></div>

The data obtained are without order. I just classify them. How should they be sorted?

Upvotes: 0

Views: 58

Answers (1)

trincot
trincot

Reputation: 350866

You can get a sorted version of tempJson by first extracting the key value pairs from it, and then sorting it with a callback function that deals with "commonly-used" separately:

let ary = [{
  "type": "search-type",
  "content": {
    "title": "google",
    "link": "https://",
  }
}, {
  "type": "study-type",
  "content": {
    "title": "w3c",
    "link": "https://",
  }
}, {
  "type": "movie-type",
  "content": {
    "title": "movie site",
    "link": "https://",
  }
}, {
  "type": "commonly-used",
  "content": {
    "title": "stackoverflow",
    "link": "https://",
  }
}, {
  "type": "tool-type",
  "content": {
    "title": "remove bg",
    "link": "https://www//",
  }
}, {
  "type": "movie-type",
  "content": {
    "title": "movie site2",
    "link": "https://",
  }
}, {
  "type": "commonly-used",
  "content": {
    "title": "github",
    "link": "https://",
  }
}, {
  "type": "search-type",
  "content": {
    "title": "wikipedia",
    "link": "https://xx",
  }
}, {
  "type": "study-type",
  "content": {
    "title": "vue",
    "link": "https://",
  }
}, {
  "type": "study-type",
  "content": {
    "title": "react",
    "link": "https://",
  }
}];

////////////////////
let tempJson = {};

ary.forEach(data => tempJson[data.type] = [])

ary.forEach(data => {
  for (const key in tempJson) {
    if (data.type === key) {
      tempJson[key].push(data.content);
      break;
    }
  }
})

let sorted = Object.entries(tempJson).sort(([a], [b]) => 
     (a != "commonly-used") - (b != "commonly-used") ||
     a.localeCompare(b)
);

for (const [classification, items] of sorted) {
  const wrapNode = `<div class="item-wrap">
    <h3>${classification}</h3>
    ${(() => {
      let contentWrapNode = ``;
      items.forEach(item => {
        const itemNode = `<div class="items"><a href="${item.link}">${item.title}</a></div>`;
        contentWrapNode += itemNode;
      })
      return contentWrapNode;
    })()}
  </div>`;

  document.querySelector('.container').innerHTML += wrapNode;
}
<div class="container"></div>

Upvotes: 2

Related Questions