Created
November 8, 2021 17:17
-
-
Save adityak74/724a12724ae85c664f58bda98643d06e to your computer and use it in GitHub Desktop.
Sort Articles by Comments and Alphabetic Hackerrank Solution
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Complete the 'topArticles' function below. | |
* | |
* The function is expected to return a STRING_ARRAY. | |
* The function accepts INTEGER limit as parameter. | |
* base url for copy/paste: | |
* https://jsonmock.hackerrank.com/api/articles?page=<pageNumber> | |
*/ | |
const https = require('https'); | |
const makeRequest = (pageNumber = 1) => new Promise((resolve, reject) => { | |
https.get(`https://jsonmock.hackerrank.com/api/articles?page=${pageNumber}`, res => { | |
let body = ""; | |
res.setEncoding("utf8"); | |
res.on("data", data => body += data); | |
res.on('end', () => { | |
const bodyParsed = JSON.parse(body); | |
resolve({ articles: bodyParsed.data, totalPages: bodyParsed.total_pages }); | |
}); | |
}); | |
}); | |
const getTitle = (article) => { | |
return article.title || article.story_title || null; | |
}; | |
async function topArticles(limit) { | |
if (limit < 0) return []; | |
const sortByCommentsAndAlpha = (a, b) => { | |
if (a.num_comments === b.num_comments) { | |
if (a.parsedName > b.parsedName) return -1; | |
else if (a.parsedName < b.parsedName) return 1; | |
return 0; | |
}; | |
if (a.num_comments > b.num_comments) return -1; | |
return 1; | |
}; | |
return new Promise(async (resolve, reject) => { | |
let articles = []; | |
const initRequest = await makeRequest(); | |
articles = articles.concat(initRequest.articles); | |
for (let i = 2; i <= initRequest.totalPages; i += 1) { | |
let newReq = await makeRequest(i); | |
articles = articles.concat(newReq.articles); | |
} | |
articles = articles.map(article => ({ ...article, parsedName: getTitle(article) })); | |
articles.sort(sortByCommentsAndAlpha); | |
articles.splice(limit); | |
resolve(articles.map(article => article.parsedName)); | |
}); | |
} | |
Python Solution.
import requests # Import the requests library for making HTTP requests
def top_articles(limit):
if limit < 0:
return []
def make_request(page_number=1):
response = requests.get(f"https://jsonmock.hackerrank.com/api/articles?page={page_number}")
response.raise_for_status() # Raise an error for bad responses
return response.json()
def get_title(article):
return article.get('title') or article.get('story_title') or None
articles = []
init_request = make_request()
articles.extend(init_request['data'])
for i in range(2, init_request['total_pages'] + 1):
new_req = make_request(i)
articles.extend(new_req['data'])
for article in articles:
article['parsed_name'] = get_title(article)
# Sort by number of comments (treat None as 0) and then alphabetically by title
articles.sort(key=lambda a: (
-a.get('num_comments', 0) if a.get('num_comments') is not None else 0,
a['parsed_name'] if a['parsed_name'] is not None else ""
))
# Limit the number of articles to the specified limit
articles = articles[:limit]
return [article['parsed_name'] for article in articles]
# Example usage
print(top_articles(2))
Here it goes (TS):
const API_URL = "https://jsonmock.hackerrank.com/api/articles";
type Article = {
title: string | null;
url: string;
author: string;
num_comments: number | null;
story_id: string | null;
story_title: string | null;
story_url: string | null;
parent_id: string | null;
created_at: string;
};
type ApiResponse = {
page: number;
per_page: number;
total: number;
total_pages: number;
data: Article[];
};
const filterArticle = (article: Article): boolean => {
return article.title !== null || article.story_title !== null;
};
const getArticleName = (article: Article): string => {
return article.title ?? article.story_title ?? '';
};
async function topArticles(limit: number): Promise<string[]> {
const fetchData = async (page: number): Promise<ApiResponse> => {
const response = await axios.get<ApiResponse>(`${API_URL}?page=${page}`);
return response.data;
};
const allArticles: { name: string; num_comments: number }[] = [];
const firstPageData = await fetchData(1);
const { total_pages } = firstPageData;
allArticles.push(
...firstPageData.data
.filter(filterArticle)
.map(article => ({
name: getArticleName(article),
num_comments: article.num_comments ?? 0,
}))
);
for (let page = 2; page <= total_pages; page++) {
const pageData = await fetchData(page);
allArticles.push(
...pageData.data
.filter(filterArticle)
.map(article => ({
name: getArticleName(article),
num_comments: article.num_comments ?? 0,
}))
);
}
allArticles.sort((a, b) => {
if (b.num_comments !== a.num_comments) {
return b.num_comments - a.num_comments;
}
return b.name.localeCompare(a.name);
});
return allArticles.slice(0, limit).map(article => article.name);
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
What if the method like this?