Start learning free

LESSON 274 OF 674 · TUPLES, SORTING & BUILT-INS

Price List in C#: Zip and Select with an Index

Practice Read the full explanation

You get a List of strings items and a List of integers prices. Return a List of strings with one line per item.

The price at each index belongs to the item at the same index.

A line looks like "1. apple: 3". It has the item's number, then the item, then its price.

The numbers start at 1. The lines keep the order of items.

 

Example 1:

Input: items = ["apple", "bread", "milk"], prices = [3, 2, 4]
Output: ["1. apple: 3", "2. bread: 2", "3. milk: 4"]
Explanation: The apple is first and costs 3.
The bread is second and costs 2.
The milk is third and costs 4.

Example 2:

Input: items = ["tea"], prices = [5]
Output: ["1. tea: 5"]
Explanation: One item gives one line, number 1.

Example 3:

Input: items = ["pen", "pen", "ink"], prices = [2, 3, 0]
Output: ["1. pen: 2", "2. pen: 3", "3. ink: 0"]
Explanation: The shop sells two kinds of pen.
Each one gets its own line, number and price.
The ink is free, so its price is 0.

 

Constraints:

  • items and prices have the same length.
  • They have 1 to 100 entries.
  • Each item is one word of lowercase letters.
  • Each price is a whole number from 0 to 1000.
STEP 1 OF 2
    Ctrl + Enter to check

    C# · TUPLES, SORTING & BUILT-INS

    Price List in C#, explained

    Problem overview

    PriceList gets a List<string> named items and a List<int> named prices of the same length. The price at each index belongs to the item at the same index. It returns a List<string> with one line per item, in the form "1. apple: 3": the item's number starting at 1, a dot and a space, the item, a colon and a space, then its price.

    For ["apple", "bread", "milk"] and [3, 2, 4] the result is ["1. apple: 3", "2. bread: 2", "3. milk: 4"]. The same item may repeat, as in ["pen", "pen", "ink"] with [2, 3, 0], and each copy gets its own line, number and price.

    Approach: pair first, then number

    Two ideas fit together here, and each has its own LINQ method.

    • items.Zip(prices, (item, price) => ...) walks the two lists side by side, so each item meets its own price. The lambda builds one string, item + ": " + price.
    • Select((entry, i) => ...) can see each entry's index i. Starting from 0, the line's number is i + 1.

    Doing the pairing first leaves lines like apple: 3. The numbering step then puts 1. in front of each. Both methods return sequences, so each ends with ToList().

    Step by step

    1. Build entries, a List<string>, from items.Zip(prices, ...) with a lambda over item and price, then ToList().
    2. Return the numbered lines: entries.Select((entry, i) => (i + 1) + ". " + entry).ToList().

    The solution in C#

    class Solution {
        public List<string> PriceList(List<string> items, List<int> prices) {
            List<string> entries = items.Zip(prices, (item, price) => item + ": " + price).ToList();
            return entries.Select((entry, i) => (i + 1) + ". " + entry).ToList();
        }
    }
    

    In item + ": " + price, the string on the left makes + join text, so the int price is turned into text automatically. In (i + 1) + ". " + entry, the parentheses make i + 1 add numbers first, and the result becomes text when it meets ". ". The parentheses are optional here, since + works from left to right and i + 1 is added first anyway, but they make the intent clear.

    Keep the order of the two steps in mind. If the numbering came first, the lines would be 1. apple and the price would still need to be attached, which means looking it up by index. Pairing first gives each line everything except its number, and the number depends only on the line's position, which is exactly what the index in Select provides.

    Complexity

    Each step makes one pass over the n items, so the time is O(n) and the extra space is O(n) for the lists of lines.

    Another way

    You can number the items and read the price by index in one Select: items.Select((item, i) => (i + 1) + ". " + item + ": " + prices[i]).ToList(). It gives the same lines for the first example. The lesson's version avoids indexing prices[i] by hand, and Zip makes the pairing of the two lists explicit.

    Testing

    Outputs from running the solution:

    items, pricesResult
    ["apple", "bread", "milk"], [3, 2, 4][1. apple: 3, 2. bread: 2, 3. milk: 4]
    ["tea"], [5][1. tea: 5]
    ["pen", "pen", "ink"], [2, 3, 0][1. pen: 2, 2. pen: 3, 3. ink: 0]

    Common mistakes

    • Starting the numbers at 0. The index is zero-based, so the number is i + 1.
    • Using a dictionary from item to price. It fails with repeated items such as the two pens. Two lists matched by position handle them.
    • Forgetting ToList(). Both Zip and Select return sequences. The method's return type is List<string>, so the last call in the chain must end with ToList(). The lesson also ends the first one with it, so entries is a real list.
    Keep going with C#500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free