---
title: How AI can streamline code reviews
teaser: Discover how seeking help from AI can save time while performing code reviews.
  See real-world examples of AI-driven efficiency in action.
tags: artificial intelligence,development,language models
author: Rakesh Arunachalam
published_on: 2025-03-17
---

Imagine having a pairing buddy to help you with those finicky Pull Request (PR)
reviews. During reviews, when it comes to refining small code snippets, Large
Language Models (LLM) using Artificial Intelligence (AI) is my new friend and
pairing buddy. Using AI, developers can quickly offer improvement suggestions
based on identified optimisation opportunities. In this blog post, I'd like to
share a few examples from my recent PR reviews, where AI not only pinpointed
precise code improvements but also provided insightful explanations on how these
changes improve the readability and performance of the code. When I say "AI" in
this post, I’m referring to text generating models like ChatGPT, Claude AI, or
DeepSeek.

It is essential to understand that AI does not review the PRs. Instead, it is
used as a tool whose primary function is to assist me with the reviews
including:

- **Informative comments**: AI helps to write thoughtful, contextual comments
  that facilitate constructive dialogue about the code.
- **Code improvements suggestions**: Alongside review comments, AI suggests code
   changes that could enhance the overall quality.

Let's dive into the examples straight away.

## Example 1: Optimising using `Map` data structure

In this example, the suspicion was an "m x n" array traversal on
`category.products` which was inefficient. I suggested an optimisation by
avoiding the "m x n" traversal using a hash map for faster lookups. AI confirmed
the approach and also provided back the refactored code as output.

### Code changes before and after refactor

```diff
export const getSelectedServerTagAssignments = (
  tagAssignments: SelectedTagAssignments[],
  defaultTagAssignments: TagSectionType[],
) => {
-  const tagAssignmentsArray = tagAssignments.map((assignment) => ({
-    id: assignment.productId,
-    quantity: assignment.quantity,
-  }))
+  const tagAssignmentsMap = new Map(
+  tagAssignments.map((assignment) => [assignment.productId, assignment]),
+  )

  return defaultTagAssignments.map((category) => ({
    ...category,
    products: category.products.map((product) => {
-      const matchingAssignment = tagAssignmentsArray.find(
-        (assignment) => assignment.id === product.id,
-      )
+      const matchingAssignment = tagAssignmentsMap.get(product.id)
      const baseProduct = {
        ...product,
        quantity: matchingAssignment ? matchingAssignment.quantity : 0,
      }
      if (!category.allowDuplicateSelections) {
        return {
          ...baseProduct,
          isSelected: !!matchingAssignment,
        }
      }
      return baseProduct
    }),
  }))
}

```

### Prompt to AI

```
// Code snippet before refactor
```

> Are the array iterations in this function implemented optimally? Can we reduce
> any iterations and determine the return value in a better way? Also any other
> ways to improve the readability of this function?

### PR Review comment

> Disclaimer: This comment was inspired by AI based on a hunch that the nested
> iteration could be avoided.
>
> This is what happens in the current version of the function:
>
> - Multiple Iterations: The function creates a tagAssignmentsArray by mapping
> over tagAssignments, and then it iterates over defaultTagAssignments with a nested
> iteration over category.products. This results in multiple iterations.
> - Redundant Property Mapping: Some properties are being mapped and re-mapped
> unnecessarily.
> - Readability: The nested structure can be hard to read and understand. I
> think we can rewrite this function to use a Map data structure
> `tagAssignmentsMap` instead of `tagAssignmentsArray` which is performant.
>
> ```
> // Code snippet after refactor
> ```
>
> I did not know `Map` data structure existed in JS/TS and was a learning for
> me. All the tests pass after the above change. What do you think?

## Example 2: Simplify for readability

When reviewing this example, it was clear at first glance that the new
conditional check had introduced a redundant `dispatch` call, and the code could
benefit from some clean-up. While drafting a comment to point this out would
have been straightforward, AI stepped in and instantly provided the elegant
refactored code. It was a small but satisfying win for efficiency.

### Code changes before and after refactor

```diff
   useEffect(() => {
     if (doesItemTagWithSections) {
+      let sections = product?.sections
       if (serverItemDetail && serverItemId) {
+        sections = getSelectedServerTagAssignments(
-        const newTagAssignments = getSelectedServerTagAssignments(
           serverItemDetail.tagAssignments,
           tagSections,
         )
-        dispatch(
-          copyTagSectionsAsync({
-            lineId: tagLineItem,
-            sections: newTagAssignments,
-          }),
-        )
-      } else {
-        dispatch(
-          copyTagSectionsAsync({
-            lineId: tagLineItem,
-            sections: product?.sections,
-          }),
-        )
       }
+      dispatch(
+        copyTagSectionsAsync({
+          lineId: tagLineItem,
+          sections,
+        }),
+      )
     }
   }, [product?.sections])

```

### Prompt to AI

```
// Code snippet before refactor
```

> Can we refactor this such that we call `dispatch` only once?

### PR Review comment

> ```
> // Code snippet after refactor
> ```

> Does this simplify the code? In this `effect`, instead of calling the
> `dispatch` twice, we get the arguments conditionally and then call `dispatch`
> once.

## Example 3: Unique keys instead of index

Passing the array `index` as a key to a React component is a common developer
mistake. While it might seem convenient, it can lead to subtle bugs. AI helped
me articulate this clearly as a PR review comment.

### Code changes before refactor

```
<FlatList 
  data={currentData} 
  keyExtractor={(item, index) => `${item.favoriteName}-${index}`}
  ...
/>
```

### Prompt to AI

```
// Code snippet above
```

Explain why it's not a good idea to use index as keys in `keyExtractor` in 50
words or less.

### PR Review comment

> Would it be good to have an `id` in the fake data and use that as a key here?
> If the list is reordered, filtered, or items are added/removed, the index of
> each item will change. This can cause React to mistakenly think that the same
> item is a different one, leading to unnecessary re-renders or incorrect
> behaviour. It's generally not a good idea to use `index` for key and also
> `name` is not guaranteed to be unique.

## Example 4: Simplify for readability

The code in this example felt verbose and hard to understand at first glance. These are the instances where you don't need to involve AI even though it's handy. Did I ask AI or not? :)

### Code changes before refactor

```
const hasTagAssignments = (orderItem: OrderLineType): boolean =>
  (orderItem.tagAssignments.length ?? 0) > 0
```

### PR Review comment

> ```
> const hasTagAssignments = (orderItem: OrderLineType): boolean =>
>   orderItem.tagAssignments?.length > 0
> ```
>
> Does this condition achieve the outcome you hope and more readable?

## Conclusion

In the past, my PR reviews and feedback might have been less detailed with only
suggestions making the developer guess the implementation details or pair
program with me to implement the same. But with AI, I've started to provide
detailed feedback with code suggestions that can be pasted immediately reducing
friction. As a result, I've received a lot of positive feedback from developers
recently making my review efforts worthwhile and rewarding.

Finally, it's essential to rely on intuition and use AI as a tool to assist in
the review process. If AI played a significant role in crafting a specific
comment, please disclose this by including a disclaimer. The final review
comment should focus on selecting the most useful insights from the AI's
responses and presenting them in a natural, human-like manner, rather than
copying the entire output returned.

Throughout this blog post, I’ve been referencing AI, and you may be wondering if
it's ChatGPT. Despite ChatGPT's popularity, I've been using different LLMs for
my code reviews. I'll write more about this and share my development workflow in
a future post. Stay tuned!
