Implement JavaScript utility and API functions
Company: Sap
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Technical Screen
Quick Answer: This question evaluates JavaScript fundamentals including string and numeric operations, array transformation and grouping, functional concepts such as currying and variadic arguments, and asynchronous HTTP interactions with a REST API.
Part 1: Concatenate Two Strings
Constraints
- 0 <= len(a), len(b) <= 100000
- a and b contain valid string characters
- The result length fits in memory
Examples
Input: ('Hello', 'World')
Expected Output: 'HelloWorld'
Explanation: The two strings are joined directly.
Input: ('', 'abc')
Expected Output: 'abc'
Explanation: Concatenating an empty first string returns the second string.
Input: ('foo', '')
Expected Output: 'foo'
Explanation: Concatenating an empty second string returns the first string.
Input: ('snow', ' flake')
Expected Output: 'snow flake'
Explanation: Spaces are ordinary characters and are preserved.
Hints
- String concatenation preserves the order of both inputs.
- The empty string should not change the other string.
Part 2: Sum Two Numbers
Constraints
- -10^12 <= x, y <= 10^12
- x and y may be integers or floating-point numbers
- The result is within the numeric range of the language
Examples
Input: (2, 3)
Expected Output: 5
Explanation: 2 + 3 = 5.
Input: (-4, 10)
Expected Output: 6
Explanation: The numbers have opposite signs.
Input: (0, 0)
Expected Output: 0
Explanation: Zero plus zero is zero.
Input: (1.5, 2.25)
Expected Output: 3.75
Explanation: Floating-point inputs are added normally.
Input: (1000000000000, 1)
Expected Output: 1000000000001
Explanation: Large integer values should be handled.
Hints
- Use ordinary numeric addition, not string concatenation.
- Negative values and zero should work without special handling.
Part 3: Build Author Full Names
Constraints
- 0 <= len(authors) <= 100000
- Each author dictionary contains string values for 'firstName', 'lastName', and 'nationality'
- Names may contain spaces or punctuation and should be preserved exactly
Examples
Input: ([{'firstName': 'Robert', 'lastName': 'Frost', 'nationality': 'American'}, {'firstName': 'Albert', 'lastName': 'Camus', 'nationality': 'French'}],)
Expected Output: ['Robert Frost', 'Albert Camus']
Explanation: Each author's first and last names are joined with a single space.
Input: ([],)
Expected Output: []
Explanation: An empty author list produces an empty name list.
Input: ([{'firstName': 'Virginia', 'lastName': 'Woolf', 'nationality': 'British'}],)
Expected Output: ['Virginia Woolf']
Explanation: A single author produces a single full-name string.
Input: ([{'firstName': 'Gabriel', 'lastName': 'Garcia Marquez', 'nationality': 'Colombian'}, {'firstName': 'Mary', 'lastName': 'Shelley', 'nationality': 'British'}],)
Expected Output: ['Gabriel Garcia Marquez', 'Mary Shelley']
Explanation: Last names containing spaces are preserved.
Hints
- Process the authors in order and transform each object into one string.
- You do not need to use nationality for this task.
Part 4: Format a Sentence Listing Authors
Constraints
- 0 <= len(authors) <= 100000
- Each author dictionary contains string values for 'firstName', 'lastName', and 'nationality'
- Preserve the input order of authors
Examples
Input: ([],)
Expected Output: 'There are no authors.'
Explanation: The empty-list edge case has a special sentence.
Input: ([{'firstName': 'Robert', 'lastName': 'Frost', 'nationality': 'American'}],)
Expected Output: 'Robert Frost is an author.'
Explanation: A single author uses singular grammar.
Input: ([{'firstName': 'Robert', 'lastName': 'Frost', 'nationality': 'American'}, {'firstName': 'Albert', 'lastName': 'Camus', 'nationality': 'French'}],)
Expected Output: 'Robert Frost and Albert Camus are authors.'
Explanation: Two authors are joined with 'and' and no comma.
Input: ([{'firstName': 'Robert', 'lastName': 'Frost', 'nationality': 'American'}, {'firstName': 'Albert', 'lastName': 'Camus', 'nationality': 'French'}, {'firstName': 'Virginia', 'lastName': 'Woolf', 'nationality': 'British'}],)
Expected Output: 'Robert Frost, Albert Camus, and Virginia Woolf are authors.'
Explanation: Three authors use commas and an Oxford comma before 'and'.
Hints
- First convert the author records into full-name strings.
- The punctuation depends on the number of names: zero, one, two, or at least three.
Part 5: Format a Sentence Listing American Authors
Constraints
- 0 <= len(authors) <= 100000
- nationality matching is case-sensitive and must equal 'American'
- Preserve the input order among matching authors
Examples
Input: ([{'firstName': 'Robert', 'lastName': 'Frost', 'nationality': 'American'}, {'firstName': 'Albert', 'lastName': 'Camus', 'nationality': 'French'}, {'firstName': 'Emily', 'lastName': 'Dickinson', 'nationality': 'American'}, {'firstName': 'Philip', 'lastName': 'Dick', 'nationality': 'American'}],)
Expected Output: 'Robert Frost, Emily Dickinson, and Philip Dick are American authors.'
Explanation: Only authors with nationality exactly equal to 'American' are included.
Input: ([],)
Expected Output: 'There are no American authors.'
Explanation: An empty list has no American authors.
Input: ([{'firstName': 'Albert', 'lastName': 'Camus', 'nationality': 'French'}, {'firstName': 'Virginia', 'lastName': 'Woolf', 'nationality': 'British'}],)
Expected Output: 'There are no American authors.'
Explanation: No records match the target nationality.
Input: ([{'firstName': 'Toni', 'lastName': 'Morrison', 'nationality': 'American'}],)
Expected Output: 'Toni Morrison is an American author.'
Explanation: A single matching author uses singular grammar.
Input: ([{'firstName': 'Robert', 'lastName': 'Frost', 'nationality': 'American'}, {'firstName': 'Margaret', 'lastName': 'Atwood', 'nationality': 'Canadian'}],)
Expected Output: 'Robert Frost is an American author.'
Explanation: Non-American authors are ignored.
Hints
- Filter the list before formatting the sentence.
- Reuse the same list-formatting idea as the all-authors sentence.
Part 6: Group Authors by Nationality
Constraints
- 0 <= len(authors) <= 100000
- Each author dictionary contains string values for 'firstName', 'lastName', and 'nationality'
- The number of distinct nationalities is at most len(authors)
Examples
Input: ([],)
Expected Output: {}
Explanation: No authors means no nationality groups.
Input: ([{'firstName': 'Robert', 'lastName': 'Frost', 'nationality': 'American'}],)
Expected Output: {'American': {'authors': ['Robert Frost'], 'count': 1}}
Explanation: A single author creates one group with count 1.
Input: ([{'firstName': 'Robert', 'lastName': 'Frost', 'nationality': 'American'}, {'firstName': 'Albert', 'lastName': 'Camus', 'nationality': 'French'}, {'firstName': 'Emily', 'lastName': 'Dickinson', 'nationality': 'American'}, {'firstName': 'Jean-Paul', 'lastName': 'Sartre', 'nationality': 'French'}],)
Expected Output: {'American': {'authors': ['Robert Frost', 'Emily Dickinson'], 'count': 2}, 'French': {'authors': ['Albert Camus', 'Jean-Paul Sartre'], 'count': 2}}
Explanation: Authors are grouped by nationality while preserving the order within each group.
Input: ([{'firstName': 'Virginia', 'lastName': 'Woolf', 'nationality': 'British'}, {'firstName': 'Mary', 'lastName': 'Shelley', 'nationality': 'British'}, {'firstName': 'Margaret', 'lastName': 'Atwood', 'nationality': 'Canadian'}],)
Expected Output: {'British': {'authors': ['Virginia Woolf', 'Mary Shelley'], 'count': 2}, 'Canadian': {'authors': ['Margaret Atwood'], 'count': 1}}
Explanation: Different nationalities create different dictionary entries.
Hints
- Use a dictionary keyed by nationality.
- When you see a nationality for the first time, initialize its authors list and count.
Part 7: Evaluate a Curried Sum
Constraints
- -10^12 <= x, y <= 10^12
- x and y may be integers or floating-point numbers
- The result is within the numeric range of the language
Examples
Input: (2, 3)
Expected Output: 5
Explanation: altSum(2)(3) evaluates to 5.
Input: (-5, 8)
Expected Output: 3
Explanation: Negative values are added normally.
Input: (0, 0)
Expected Output: 0
Explanation: The zero edge case returns zero.
Input: (1.5, 2.5)
Expected Output: 4.0
Explanation: Floating-point values are supported.
Hints
- A curried function can be represented as a function that returns another function.
- The final returned value is still just the arithmetic sum.
Part 8: Sum Any Number of Arguments
Constraints
- 0 <= number of arguments <= 100000
- -10^12 <= each argument <= 10^12
- Arguments may be integers or floating-point numbers
Examples
Input: (1, 2, 3, 4)
Expected Output: 10
Explanation: 1 + 2 + 3 + 4 = 10.
Input: ()
Expected Output: 0
Explanation: With no arguments, the total is defined as 0.
Input: (-1, 5, -4)
Expected Output: 0
Explanation: The positive and negative values cancel out.
Input: (2.5, 0.5, 1)
Expected Output: 4.0
Explanation: Floating-point values are summed normally.
Input: (1000000000000, 1, -2)
Expected Output: 999999999999
Explanation: Large values should be handled correctly.
Hints
- Initialize a running total to 0.
- Then add each provided number to the running total.
Part 9: Extract the First Ten Pokémon Summaries
Constraints
- 0 <= len(api_response.get('results', [])) <= 100000
- Each result contains string keys 'name' and 'url'
- Ignore extra fields in each result object
Examples
Input: ({'results': [{'name': 'bulbasaur', 'url': 'https://pokeapi.co/api/v2/pokemon/1/'}, {'name': 'ivysaur', 'url': 'https://pokeapi.co/api/v2/pokemon/2/'}]},)
Expected Output: [{'name': 'bulbasaur', 'url': 'https://pokeapi.co/api/v2/pokemon/1/'}, {'name': 'ivysaur', 'url': 'https://pokeapi.co/api/v2/pokemon/2/'}]
Explanation: The returned objects keep only name and url.
Input: ({'results': []},)
Expected Output: []
Explanation: An empty results list returns an empty list.
Input: ({},)
Expected Output: []
Explanation: A missing results field is handled as an empty list.
Input: ({'results': [{'name': 'bulbasaur', 'url': 'u1', 'id': 1}, {'name': 'ivysaur', 'url': 'u2', 'extra': True}]},)
Expected Output: [{'name': 'bulbasaur', 'url': 'u1'}, {'name': 'ivysaur', 'url': 'u2'}]
Explanation: Extra fields are ignored.
Input: ({'results': [{'name': 'p1', 'url': 'u1'}, {'name': 'p2', 'url': 'u2'}, {'name': 'p3', 'url': 'u3'}, {'name': 'p4', 'url': 'u4'}, {'name': 'p5', 'url': 'u5'}, {'name': 'p6', 'url': 'u6'}, {'name': 'p7', 'url': 'u7'}, {'name': 'p8', 'url': 'u8'}, {'name': 'p9', 'url': 'u9'}, {'name': 'p10', 'url': 'u10'}, {'name': 'p11', 'url': 'u11'}]},)
Expected Output: [{'name': 'p1', 'url': 'u1'}, {'name': 'p2', 'url': 'u2'}, {'name': 'p3', 'url': 'u3'}, {'name': 'p4', 'url': 'u4'}, {'name': 'p5', 'url': 'u5'}, {'name': 'p6', 'url': 'u6'}, {'name': 'p7', 'url': 'u7'}, {'name': 'p8', 'url': 'u8'}, {'name': 'p9', 'url': 'u9'}, {'name': 'p10', 'url': 'u10'}]
Explanation: Only the first 10 results are returned.
Hints
- Look inside the 'results' field of the response.
- Slice to the first 10 entries, then project each entry down to only name and url.
Part 10: Build Display Data for Pokémon Details
Constraints
- 0 <= len(pokemon_list) <= 10
- Each summary contains string keys 'name' and 'url'
- Each available detail may contain 'name', 'height', 'weight', and nested 'sprites' with 'front_default'
- If sprites.front_default is missing, use None for img
Examples
Input: ([{'name': 'bulbasaur', 'url': 'u1'}, {'name': 'ivysaur', 'url': 'u2'}], {'u1': {'name': 'bulbasaur', 'height': 7, 'weight': 69, 'sprites': {'front_default': 'img1'}}, 'u2': {'name': 'ivysaur', 'height': 10, 'weight': 130, 'sprites': {'front_default': 'img2'}}})
Expected Output: [{'name': 'bulbasaur', 'height': 7, 'weight': 69, 'img': 'img1'}, {'name': 'ivysaur', 'height': 10, 'weight': 130, 'img': 'img2'}]
Explanation: Each summary URL is used to look up its detail response.
Input: ([], {})
Expected Output: []
Explanation: No Pokémon summaries means no display objects.
Input: ([{'name': 'charmander', 'url': 'u4'}], {'u4': {'name': 'charmander', 'height': 6, 'weight': 85, 'sprites': {}}})
Expected Output: [{'name': 'charmander', 'height': 6, 'weight': 85, 'img': None}]
Explanation: Missing sprites.front_default becomes None.
Input: ([{'name': 'squirtle', 'url': 'u7'}], {'u7': {'height': 5, 'weight': 90, 'sprites': {'front_default': 'img7'}}})
Expected Output: [{'name': 'squirtle', 'height': 5, 'weight': 90, 'img': 'img7'}]
Explanation: If the detail lacks a name, the summary name is used.
Hints
- For each summary, use its url to find the corresponding detail object.
- The image URL is nested under the sprites object.