<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Omkar's Software Sage]]></title><description><![CDATA[Hi there! I'm Omkar, a passionate software developer with a love for crafting elegant solutions to complex problems.]]></description><link>https://blog.omkarkirpan.com</link><generator>RSS for Node</generator><lastBuildDate>Sun, 13 Sep 2026 18:12:30 GMT</lastBuildDate><atom:link href="https://blog.omkarkirpan.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Optimizing Node.js with Neon: Expert Strategies for Rust Binding Writing]]></title><description><![CDATA[Node.js is a popular tool for running JavaScript on servers but can sometimes struggle with heavy-duty tasks. That's where Neon comes in. It's like a sidekick for Node.js, using Rust's muscle to make things run smoother and quicker.
Think of Neon as ...]]></description><link>https://blog.omkarkirpan.com/optimizing-nodejs-with-neon-expert-strategies-for-rust-binding-writing</link><guid isPermaLink="true">https://blog.omkarkirpan.com/optimizing-nodejs-with-neon-expert-strategies-for-rust-binding-writing</guid><category><![CDATA[rust binding]]></category><category><![CDATA[Rust]]></category><category><![CDATA[rust lang]]></category><category><![CDATA[Node.js]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[neon]]></category><category><![CDATA[modules]]></category><category><![CDATA[performance]]></category><category><![CDATA[optimization]]></category><dc:creator><![CDATA[Omkar Kirpan]]></dc:creator><pubDate>Sat, 09 Mar 2024 14:24:58 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1709994207104/6ea0ace9-366c-425c-bfd8-1ba634bf4ca8.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Node.js is a popular tool for running JavaScript on servers but can sometimes struggle with heavy-duty tasks. That's where Neon comes in. It's like a sidekick for Node.js, using Rust's muscle to make things run smoother and quicker.</p>
<p>Think of Neon as a cousin to WebAssembly (or Wasm for short). Both let you add Rust's superpowers to your project. But while Wasm changes Rust into a different language, Neon keeps it as is, turning it into the kind of code your computer uses naturally. This trick helps your project zip along faster than it would with Wasm.</p>
<p>One of Neon's neat tricks is that it plays nice with nearly everything Rust can do. This lets you mix Rust's swiftness and smarty-pants tools into your Node.js project to give it a boost.</p>
<p>We're about to take a closer look at what Neon is all about and how it can make your application zip along with the help of Rust. Let's get started!</p>
<h2 id="heading-what-is-neon">What is Neon?</h2>
<p>Let's explore <a target="_blank" href="https://neon-bindings.com/">Neon</a>, a remarkable toolkit designed for Node.js applications to seamlessly integrate with Rust's robust capabilities. Neon serves as a bridge, allowing developers to craft native bindings—specialized libraries that are executed directly by the computer's hardware, enhancing the app's performance immensely.</p>
<p>As opposed to typical Node modules, which are interpreted, native bindings are pre-compiled into the machine's native language, offering a turbocharged experience for any process they engage with.</p>
<h2 id="heading-why-neon">Why Neon?</h2>
<p>Here's why Neon shines: Neon elevates your Node.js projects by allowing you to harness Rust's power—envision the raw speed, enhanced concurrency through threading, and a treasure trove of Rust’s packages. Plus, you gain direct access to libraries native to your operating system.</p>
<p>Craft native Node modules, akin to those you'd build with C or C++, but leave behind the complexities and potential risks that come with low-level systems programming. Neon's user-friendly CLI and its adherence to best practices pave the way for a smoother construction of native modules, freeing you from the typical encumbrances of native development.</p>
<h2 id="heading-how-to-create-a-neon-project">How to create a Neon project</h2>
<p>Starting a Neon project is really easy, but you have to make sure that you've already installed two things on your computer: <a target="_blank" href="https://nodejs.org/en">Node.js</a> and <a target="_blank" href="https://www.rust-lang.org/tools/install">Rust</a>. Neon needs them to work properly.</p>
<p>If you've got those set up, here's what you need to do next:</p>
<ol>
<li><p>Open your terminal. This is like the command center where you type in instructions for your computer.</p>
</li>
<li><p>Check that you're in the place where you want your new project to be made. If not, move to the right spot using the 'cd' command (like 'cd Documents/my_projects').</p>
</li>
<li><p>Once you're there, type this command in the terminal and press Enter:</p>
</li>
</ol>
<pre><code class="lang-bash">npm init neon my-project
</code></pre>
<p>After you do that, your computer will make a new folder in that spot, and it will name the folder <code>my-project</code> (or whatever name you choose to put at the end of that command). Make sure you don't put any spaces in the project name you choose!</p>
<p>The project folder will have this structure:</p>
<pre><code class="lang-plaintext">.
├── Cargo.toml
├── README.md
├── package.json
└── src
    └── lib.rs
</code></pre>
<p>Let’s take a closer look at the unique structure of our Neon project.</p>
<h2 id="heading-neon-project-structure">Neon project structure</h2>
<p>The way a Neon project is set up is pretty neat. Think of it as a mix of two types of projects: one part is for Node.js and the other part is for a Rust library. That's the standard setup for Neon projects.</p>
<p>Here's where the magic happens:</p>
<ul>
<li><p>For the Rust part, you'll be working in a file called <code>src/</code><a target="_blank" href="https://github.com/OmkarKirpan/rust-bindings-with-neon/blob/main/my-project/src/lib.rs"><code>lib.rs</code></a>. That's where you'll write your Rust code, known as "bindings." These bindings are like special translators that let Node.js understand Rust functions.</p>
</li>
<li><p>For the JavaScript part, your files can be scattered around the project folder wherever you feel is best.</p>
</li>
</ul>
<p>Zooming into the Rust side a bit more:</p>
<h3 id="heading-the-librshttpsgithubcomomkarkirpanrust-bindings-with-neonblobmainmy-projectsrclibrs-file">The <a target="_blank" href="https://github.com/OmkarKirpan/rust-bindings-with-neon/blob/main/my-project/src/lib.rs"><code>lib.rs</code></a> File:</h3>
<p>The Rust library file contains the following code:</p>
<pre><code class="lang-rust"><span class="hljs-keyword">use</span> neon::prelude::*;

<span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">hello</span></span>(<span class="hljs-keyword">mut</span> cx: FunctionContext) -&gt; JsResult&lt;JsString&gt; {
    <span class="hljs-literal">Ok</span>(cx.string(<span class="hljs-string">"hello node"</span>))
}

<span class="hljs-meta">#[neon::main]</span>
<span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">main</span></span>(<span class="hljs-keyword">mut</span> cx: ModuleContext) -&gt; NeonResult&lt;()&gt; {
    cx.export_function(<span class="hljs-string">"hello"</span>, hello)?;
    <span class="hljs-literal">Ok</span>(())
}
</code></pre>
<p>The Rust library <a target="_blank" href="https://github.com/OmkarKirpan/rust-bindings-with-neon/blob/main/my-project/src/lib.rs"><code>lib.rs</code></a> file serves as a bridge between the high-performance world of Rust and the flexible environment of Node.js. Let's break it down into simpler terms:</p>
<ol>
<li><p><strong>Including Necessary Tools</strong>: At the very top in line one, <code>use neon::prelude::*;</code> is like grabbing a toolbox. This line tells Rust to bring in a bunch of tools and materials you're going to need for the rest of your code.</p>
</li>
<li><p><strong>The Friendly</strong> <code>hello</code> Function: Lines three to five focus on a function named <code>hello</code>. This isn't just any function; it's special because it's made to be used directly in your JavaScript code. When you call <code>hello</code> from JavaScript, what you're actually getting is a friendly greeting from Rust, "hello node," which is created and sent back as a JavaScript string.</p>
</li>
<li><p><strong>Setting Up the Welcome Mat with</strong> <code>main</code>: The chunk of code from lines seven to eleven acts as the welcome mat for your Rust functions. It sets things up so that when your JavaScript code starts running, it knows exactly where to find the <code>hello</code> function. It's like a signpost that says, "Hello function available here!"</p>
</li>
</ol>
<p>Now, diving into the nitty-gritty:</p>
<ul>
<li><p>The argument <code>cx</code> in the <code>hello</code> function is your key to working with JavaScript. It lets you speak JavaScript's language from within Rust. In this case, you're using it to make a brand new string that says "hello node."</p>
</li>
<li><p><code>JsResult&lt;JsString&gt;</code> is a way of saying, "Hey, I'm going to give you a string, but just to be safe, I'm wrapping it in a special package that makes sure everything goes smoothly when I hand it over to JavaScript."</p>
</li>
<li><p>The <code>Ok(...)</code> part is Rust's way of giving a thumbs-up, saying "All good here!" It wraps up the "hello node" string so that it's ready to be used by JavaScript without any issues.</p>
</li>
<li><p>As for the <code>main</code> function, think of it as the director of a play. It's where you point out to Neon: "See that <code>hello</code> function? It has a part to play in our JavaScript world." And just like the <code>hello</code> function, <code>cx</code> is used here, but this time it's for attaching the <code>hello</code> function to the grand stage of JavaScript.</p>
</li>
<li><p>And finally, the <code>NeonResult&lt;()&gt;</code> return type is like a guarantee sign-off. It's Rust's way of saying, "I have done my part, and everything is set up correctly for JavaScript to use."</p>
</li>
</ul>
<h2 id="heading-interacting-with-the-rust-library-in-javascript">Interacting with the Rust library in JavaScript</h2>
<p>Great, you're ready to make your JavaScript code and Rust library work together!</p>
<p>To set the stage for this interaction, follow these two steps:</p>
<ol>
<li><p><strong>Install JavaScript Dependencies</strong>: Open your terminal and run the <code>npm install</code> command (or <code>npm i</code> for short). This command tells npm, which is like a personal shopping assistant for code, to go out and fetch all the bits and bobs your JavaScript code needs to run smoothly.</p>
<p> Just type this in your terminal:</p>
<pre><code class="lang-bash"> npm i
</code></pre>
</li>
<li><p><strong>Build the Rust Library</strong>: Once your JavaScript is all set with its dependencies, you need to compile your Rust code so it can mingle with JavaScript. For this, you'll use the command <code>npm run build</code>. This is like telling a builder to take all your neatly written Rust instructions and turn them into something solid and usable that JavaScript can understand.</p>
<p> In your terminal, type:</p>
<pre><code class="lang-bash"> npm run build
</code></pre>
</li>
</ol>
<p>After you finish that, you can try it out using Node's interactive shell.</p>
<pre><code class="lang-bash">node                                                                                                                         ─╯
Welcome to Node.js v21.4.0.
Type <span class="hljs-string">".help"</span> <span class="hljs-keyword">for</span> more information.
&gt; const mod = require(<span class="hljs-string">"."</span>)
undefined
&gt; mod.hello()
<span class="hljs-string">'hello node'</span>
&gt;
</code></pre>
<p>You can also test it using a regular JavaScript file. Just make a file called <code>index.js</code>, paste the code given below into it, and then run <code>node index.js</code>.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> mod = <span class="hljs-built_in">require</span>(<span class="hljs-string">"."</span>);
<span class="hljs-built_in">console</span>.log(mod.hello());
</code></pre>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In summary, Neon is a useful tool that makes Node.js projects much better by combining the strength and security of Rust. It lets you take advantage of all the cool features Rust offers. I hope this guide has made it easier for you to understand Neon.</p>
<p>To get a practical understanding and see the code in action, the <a target="_blank" href="https://github.com/OmkarKirpan/rust-bindings-with-neon/tree/main">GitHub repository</a> for this tutorial will be your go-to resource. It houses all the code snippets we've touched upon, enabling you to review and try them out in your own environment.</p>
<p>And if you have any questions about using Neon to connect Node.js with Rust, feel free to ask in the comments below. Thanks for reading!</p>
]]></content:encoded></item><item><title><![CDATA[Mastering jq: The Ultimate Guide to Data Transformation Like a Pro]]></title><description><![CDATA[1. Overview
JSON is a popular structured data format that is utilized in most modern APIs and data services. It is especially popular in online applications because of its lightweight design and interoperability with JavaScript.
Unfortunately, shells...]]></description><link>https://blog.omkarkirpan.com/mastering-jq-the-ultimate-guide-to-data-transformation-like-a-pro</link><guid isPermaLink="true">https://blog.omkarkirpan.com/mastering-jq-the-ultimate-guide-to-data-transformation-like-a-pro</guid><category><![CDATA[jq]]></category><category><![CDATA[json]]></category><category><![CDATA[json parser]]></category><category><![CDATA[shell]]></category><category><![CDATA[shell scripting]]></category><category><![CDATA[Devops]]></category><category><![CDATA[Developer]]></category><category><![CDATA[Linux]]></category><category><![CDATA[Beginner Developers]]></category><category><![CDATA[linux-basics]]></category><category><![CDATA[Bash]]></category><dc:creator><![CDATA[Omkar Kirpan]]></dc:creator><pubDate>Mon, 26 Feb 2024 13:09:39 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1708952523927/647043d8-c1e0-4efe-bf0b-59f5ca047c26.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-1-overview"><strong>1. Overview</strong></h2>
<p><a target="_blank" href="https://www.json.org/json-en.html">JSON</a> is a popular structured data format that is utilized in most modern APIs and data services. It is especially popular in online applications because of its lightweight design and interoperability with JavaScript.</p>
<p><strong>Unfortunately, shells like Bash are unable to understand and manipulate JSON natively.</strong> This implies that dealing with JSON via the command line can be time-consuming, as it requires text manipulation using tools like <a target="_blank" href="http://man7.org/linux/man-pages/man1/sed.1.html"><em>sed</em></a> and <a target="_blank" href="https://www.baeldung.com/linux/common-text-search"><em>grep</em></a>.</p>
<h2 id="heading-2-installation"><strong>2. Installation</strong></h2>
<p>Let’s begin by <a target="_blank" href="https://github.com/stedolan/jq/wiki/Installation">installing</a> <em>jq</em>, which is <a target="_blank" href="https://stedolan.github.io/jq/download/">available</a> in most operating system packaging repositories. <strong>It’s also possible to download the binary directly or build it from the source.</strong></p>
<p>Once we’ve installed the package, let’s verify the installation by running <em>jq</em>:</p>
<pre><code class="lang-bash">$ jq
jq - commandline JSON processor [version 1.6]

Usage:    jq [options] &lt;jq filter&gt; [file...]
    jq [options] --args &lt;jq filter&gt; [strings...]
    jq [options] --jsonargs &lt;jq filter&gt; [JSON_TEXTS...]
...
</code></pre>
<p>If the installation was successful, the console will display the version, usage examples, and other information.</p>
<h2 id="heading-3-working-with-simple-filters"><strong>3. Working With Simple Filters</strong></h2>
<p><strong><em>jq</em> is based on the concept of filters that operate on a stream of JSON.</strong> Each filter accepts an input and returns JSON to the standard output. As we will see, there are numerous preconfigured filters that we can use. We can easily combine these filters with pipelines to quickly create and apply complicated operations and transformations to our JSON data.</p>
<h3 id="heading-31-prettify-json"><strong>3.1. Prettify JSON</strong></h3>
<p>Let’s start by taking a look at the simplest filter of all, which incidentally is one of the most useful and frequently used features of <em>jq</em>:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">echo</span> <span class="hljs-string">'{"fruit":{"name":"apple","color":"green","price":1.20}}'</span> | jq <span class="hljs-string">'.'</span>
</code></pre>
<p>We <a target="_blank" href="http://man7.org/linux/man-pages/man1/echo.1.html"><em>echo</em></a> a simple JSON string and pipe it directly into our <em>jq</em> command. Then we use the identity filter ‘.’ that takes the input and produces it unchanged as output with the caveat that by default <em>jq</em> pretty-prints all output.</p>
<p>This gives us the following output:</p>
<pre><code class="lang-bash">{
  <span class="hljs-string">"fruit"</span>: {
    <span class="hljs-string">"name"</span>: <span class="hljs-string">"apple"</span>,
    <span class="hljs-string">"color"</span>: <span class="hljs-string">"green"</span>,
    <span class="hljs-string">"price"</span>: 1.2
  }
}
</code></pre>
<p>We can also apply this filter directly to a JSON file:</p>
<pre><code class="lang-bash">jq <span class="hljs-string">'.'</span> fruit.json
</code></pre>
<p><strong>Being able to prettify JSON is particularly useful when we want to retrieve data from an API and see the response in a clear, readable format.</strong></p>
<p>Let’s hit a simple API using <a target="_blank" href="https://curl.haxx.se/"><em>curl</em></a> to see this in practice:</p>
<pre><code class="lang-bash">curl http://api.open-notify.org/iss-now.json | jq <span class="hljs-string">'.'</span>
</code></pre>
<p>This gives us a JSON response for the current position of the International Space Station:</p>
<pre><code class="lang-bash">{
  <span class="hljs-string">"message"</span>: <span class="hljs-string">"success"</span>,
  <span class="hljs-string">"timestamp"</span>: 1572386230,
  <span class="hljs-string">"iss_position"</span>: {
    <span class="hljs-string">"longitude"</span>: <span class="hljs-string">"-35.4232"</span>,
    <span class="hljs-string">"latitude"</span>: <span class="hljs-string">"-51.3109"</span>
  }
}
</code></pre>
<h3 id="heading-32-accessing-properties"><strong>3.2. Accessing Properties</strong></h3>
<p><strong>We can access property values by using another simple filter: the <em>.field</em> operator.</strong> To find a property value, we simply combine this filter followed by the property name.</p>
<p>Let’s see this by building on our simple fruit example:</p>
<pre><code class="lang-bash">jq <span class="hljs-string">'.fruit'</span> fruit.json
</code></pre>
<p>Here, we are accessing the fruit property, which gives us all the children of this key:</p>
<pre><code class="lang-bash">{
  <span class="hljs-string">"name"</span>: <span class="hljs-string">"apple"</span>,
  <span class="hljs-string">"color"</span>: <span class="hljs-string">"green"</span>,
  <span class="hljs-string">"price"</span>: 1.2
}
</code></pre>
<p>We can also chain property values together, allowing us to access nested objects:</p>
<pre><code class="lang-bash">jq <span class="hljs-string">'.fruit.color'</span> fruit.json
</code></pre>
<p>As expected, this simply returns the color of our fruit:</p>
<pre><code class="lang-bash"><span class="hljs-string">"green"</span>
</code></pre>
<p>If we need to retrieve multiple keys, we can separate them using a comma:</p>
<pre><code class="lang-bash">jq <span class="hljs-string">'.fruit.color,.fruit.price'</span> fruit.json
</code></pre>
<p>This results in an output containing both property values:</p>
<pre><code class="lang-bash"><span class="hljs-string">"green"</span>
1.2
</code></pre>
<p><strong>Note that if one of the properties has spaces or special characters, we need to wrap the property name in quotes when accessing it from the <em>jq</em> command</strong>:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">echo</span> <span class="hljs-string">'{ "with space": "hello" }'</span> | jq <span class="hljs-string">'."with space"'</span>
</code></pre>
<h2 id="heading-4-json-arrays"><strong>4. JSON Arrays</strong></h2>
<p><strong>Now let's look at how to work with arrays in JSON data.</strong> Arrays are commonly used to represent lists of elements. In addition, as in many programming languages, square brackets are used to designate the beginning and end of an array.</p>
<h3 id="heading-41-iteration"><strong>4.1. Iteration</strong></h3>
<p>We’ll start with a basic example to demonstrate how to iterate over an array:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">echo</span> <span class="hljs-string">'["x","y","z"]'</span> | jq <span class="hljs-string">'.[]'</span>
</code></pre>
<p>Here, we see the object value iterator operator <em>.[]</em> in use, which will print out each item in the array on a separate line:</p>
<pre><code class="lang-bash"><span class="hljs-string">"x"</span>
<span class="hljs-string">"y"</span>
<span class="hljs-string">"z"</span>
</code></pre>
<p>Now let’s imagine we want to represent a list of fruit in a JSON document:</p>
<pre><code class="lang-json">[
  {
    <span class="hljs-attr">"name"</span>: <span class="hljs-string">"apple"</span>,
    <span class="hljs-attr">"color"</span>: <span class="hljs-string">"green"</span>,
    <span class="hljs-attr">"price"</span>: <span class="hljs-number">1.2</span>
  },
  {
    <span class="hljs-attr">"name"</span>: <span class="hljs-string">"banana"</span>,
    <span class="hljs-attr">"color"</span>: <span class="hljs-string">"yellow"</span>,
    <span class="hljs-attr">"price"</span>: <span class="hljs-number">0.5</span>
  },
  {
    <span class="hljs-attr">"name"</span>: <span class="hljs-string">"kiwi"</span>,
    <span class="hljs-attr">"color"</span>: <span class="hljs-string">"green"</span>,
    <span class="hljs-attr">"price"</span>: <span class="hljs-number">1.25</span>
  }
]
</code></pre>
<p>Each item in the array is an object that represents a fruit.</p>
<p><strong>Let’s see how to extract the name of each fruit from each object in the array</strong>:</p>
<pre><code class="lang-bash">jq <span class="hljs-string">'.[] | .name'</span> fruits.json
</code></pre>
<p>First, we iterate over the array using <em>.[]</em>. Then we can pass each object in the array to the next filter in the command using a pipe |. The last step is to output the name field from each object using <em>.name</em>:</p>
<pre><code class="lang-bash"><span class="hljs-string">"apple"</span>
<span class="hljs-string">"banana"</span>
<span class="hljs-string">"kiwi"</span>
</code></pre>
<p><strong>We can also use a slightly more concise version and access the property directly on each object in the array</strong>:</p>
<pre><code class="lang-bash">jq <span class="hljs-string">'.[].name'</span> fruits.json
</code></pre>
<h3 id="heading-42-accessing-by-index"><strong>4.2. Accessing by Index</strong></h3>
<p>Of course, as with all arrays, we can access one of the items in the array directly by passing the index:</p>
<pre><code class="lang-bash">jq <span class="hljs-string">'.[1].price'</span> fruits.json
</code></pre>
<h3 id="heading-43-slicing"><strong>4.3. Slicing</strong></h3>
<p><strong>Finally, <em>jq</em> also supports slicing of arrays, another powerful feature.</strong> This is particularly useful when we need to return a subarray of an array.</p>
<p>Again, let’s see this using a simple array of numbers:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">echo</span> <span class="hljs-string">'[1,2,3,4,5,6,7,8,9,10]'</span> | jq <span class="hljs-string">'.[6:9]'</span>
</code></pre>
<p>The result will be a new array with a length of 3, containing the elements from index 6 (inclusive) to index 9 (exclusive):</p>
<pre><code class="lang-bash">[
  7,
  8,
  9
]
</code></pre>
<p>It’s also possible to omit one of the indexes when using the slicing functionality:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">echo</span> <span class="hljs-string">'[1,2,3,4,5,6,7,8,9,10]'</span> | jq <span class="hljs-string">'.[:6]'</span> | jq <span class="hljs-string">'.[-2:]'</span>
</code></pre>
<p>Since we specified only the second argument in <em>.[:6]</em>, the slice will start from the beginning of the array and run up until index 6. It’s the same as doing <em>.[0:6]</em>.</p>
<p><strong>The second slicing operation has a negative argument, which denotes in this case that it counts backward from the end of the array.</strong></p>
<p>Note the subtle difference in the second slice — we pass the index as the first argument. <strong>This means we will start two indexes from the end (-2), and since the second argument is empty, it will run until the end of the array.</strong></p>
<p>This gives us the following output:</p>
<pre><code class="lang-bash">[
  5,
  6
]
</code></pre>
<h2 id="heading-5-using-functions"><strong>5. Using Functions</strong></h2>
<p><em>jq</em> has many powerful built-in functions that we can use to perform a variety of useful operations. Let’s take a look at some of them now.</p>
<h3 id="heading-51-getting-keys"><strong>5.1. Getting Keys</strong></h3>
<p><strong>Sometimes, we may want to get the keys of an object as an array instead of the values.</strong></p>
<p>We can do this using the <em>keys</em> function:</p>
<pre><code class="lang-bash">jq <span class="hljs-string">'.fruit | keys'</span> fruit.json
</code></pre>
<p>This gives us the keys sorted alphabetically:</p>
<pre><code class="lang-bash">[
  <span class="hljs-string">"color"</span>,
  <span class="hljs-string">"name"</span>,
  <span class="hljs-string">"price"</span>
]
</code></pre>
<h3 id="heading-52-returning-the-length"><strong>5.2. Returning the Length</strong></h3>
<p>Another handy function for arrays and objects is the <em>length</em> function.</p>
<p><strong>We can use this function to return the array’s length or the number of properties on an object</strong>:</p>
<pre><code class="lang-bash">jq <span class="hljs-string">'.fruit | length'</span> fruit.json
</code></pre>
<p>Here, we get “3” since the fruit object has three properties.</p>
<p><strong>We can even use the <em>length</em> function on string values as well</strong>:</p>
<pre><code class="lang-bash">jq <span class="hljs-string">'.fruit.name | length'</span> fruit.json
</code></pre>
<p>We would see “5” as the resulting output since the fruit name property has five characters: “apple”.</p>
<h3 id="heading-53-mapping-values"><strong>5.3. Mapping Values</strong></h3>
<p><strong>The <em>map</em> function is a powerful function we can use to apply a filter or function to an array</strong>:</p>
<pre><code class="lang-bash">jq <span class="hljs-string">'map(has("name"))'</span> fruits.json
</code></pre>
<p><strong>In this example, we’re applying the <em>has</em> function to each item in the array and looking to see if there is a name property.</strong> In our simple fruits JSON, we get <em>true</em> in each result item.</p>
<p><strong>We can also use the <em>map</em> function to apply operations to the elements in an array.</strong></p>
<p>Let’s imagine we want to increase the price of each fruit:</p>
<pre><code class="lang-bash">jq <span class="hljs-string">'map(.price+2)'</span> fruits.json
</code></pre>
<p>This gives us a new array with each price incremented:</p>
<pre><code class="lang-bash">[
  3.2,
  2.5,
  3.25
]
</code></pre>
<h3 id="heading-54-min-and-max"><strong>5.4. Min and Max</strong></h3>
<p><strong>If we need to find the minimum or maximum element of an input array, we can utilize the <em>min</em> and <em>max</em> functions</strong>:</p>
<pre><code class="lang-bash">jq <span class="hljs-string">'[.[].price] | min'</span> fruits.json
</code></pre>
<p>Likewise, we can also find the most expensive fruit in our JSON document:</p>
<pre><code class="lang-bash">jq <span class="hljs-string">'[.[].price] | max'</span> fruits.json
</code></pre>
<p>Note that in these two examples, we’ve constructed a new array, using <em>[]</em> around the array iteration. <strong>This contains only the prices before we pass this new list to the <em>min</em> or <em>max</em> function.</strong></p>
<h3 id="heading-55-selecting-values"><strong>5.5. Selecting Values</strong></h3>
<p><strong>The <em>select</em> function is another impressive utility that we can use for querying JSON.</strong></p>
<p><strong>We can think of it as a bit like a simple version of XPath for JSON</strong>:</p>
<pre><code class="lang-bash">jq <span class="hljs-string">'.[] | select(.price&gt;0.5)'</span> fruits.json
</code></pre>
<p>This selects all the fruit with a price greater than 0.5.</p>
<p><strong>Likewise, we can also make selections based on the value of a property</strong>:</p>
<pre><code class="lang-bash">jq <span class="hljs-string">'.[] | select(.color=="yellow")'</span> fruits.json
</code></pre>
<p>We can even combine conditions to build up complex selections:</p>
<pre><code class="lang-bash">jq <span class="hljs-string">'.[] | select(.color=="yellow" and .price&gt;=0.5)'</span> fruits.json
</code></pre>
<p>This will give us all yellow fruit matching a given price condition:</p>
<pre><code class="lang-bash">{
  <span class="hljs-string">"name"</span>: <span class="hljs-string">"banana"</span>,
  <span class="hljs-string">"color"</span>: <span class="hljs-string">"yellow"</span>,
  <span class="hljs-string">"price"</span>: 0.5
}
</code></pre>
<h3 id="heading-56-support-for-regular-expressions"><strong>5.6. Support for Regular Expressions</strong></h3>
<p><strong>Next, we’re going to look at the <em>test</em> function, which enables us to test if an input matches against a given regular expression</strong>:</p>
<pre><code class="lang-bash">jq <span class="hljs-string">'.[] | select(.name|test("^a.")) | .price'</span> fruits.json
</code></pre>
<p>Simply put, we want to output the price of all the fruit whose name starts with the letter “a”.</p>
<h3 id="heading-57-finding-unique-values"><strong>5.7. Finding Unique Values</strong></h3>
<p><strong>One common use case is to be able to see unique occurrences of a particular value within an array or remove duplicates.</strong></p>
<p>Let’s see how many unique colors we have in our fruits JSON document:</p>
<pre><code class="lang-bash">jq <span class="hljs-string">'map(.color) | unique'</span> fruits.json
</code></pre>
<p>We use the <em>map</em> function to create a new array containing only colors. <strong>Then we pass each color in the new array to the <em>unique</em> function using a pipe |.</strong></p>
<p>This gives us an array with two distinct fruit colors:</p>
<pre><code class="lang-bash">[
  <span class="hljs-string">"green"</span>,
  <span class="hljs-string">"yellow"</span>
]
</code></pre>
<h3 id="heading-58-deleting-keys-from-json"><strong>5.8. Deleting Keys From JSON</strong></h3>
<p><strong>We’ll also sometimes want to remove a key and corresponding value from JSON objects.</strong></p>
<p>For this, <em>jq</em> provides the <em>del</em> function:</p>
<pre><code class="lang-bash">jq <span class="hljs-string">'del(.fruit.name)'</span> fruit.json
</code></pre>
<p>This outputs the fruit object without the deleted key:</p>
<pre><code class="lang-bash">{
  <span class="hljs-string">"fruit"</span>: {
    <span class="hljs-string">"color"</span>: <span class="hljs-string">"green"</span>,
    <span class="hljs-string">"price"</span>: 1.2
  }
}
</code></pre>
<h2 id="heading-6-transforming-json"><strong>6. Transforming JSON</strong></h2>
<p>Frequently, when working with data structures such as JSON, we might want to transform one data structure into another. <strong>This can be useful while working with large JSON structures when we are only interested in several properties or values.</strong></p>
<p>In this example, we’ll use some Wikipedia JSON that describes a list of page entries:</p>
<pre><code class="lang-bash">{
  <span class="hljs-string">"query"</span>: {
    <span class="hljs-string">"pages"</span>: [
      {
        <span class="hljs-string">"21721050"</span>: {
          <span class="hljs-string">"pageid"</span>: 21721050,
          <span class="hljs-string">"ns"</span>: 0,
          <span class="hljs-string">"title"</span>: <span class="hljs-string">"Stack Overflow"</span>,
          <span class="hljs-string">"extract"</span>: <span class="hljs-string">"Some interesting text about Stack Overflow"</span>
        }
      },
      {
        <span class="hljs-string">"21721051"</span>: {
          <span class="hljs-string">"pageid"</span>: 21721051,
          <span class="hljs-string">"ns"</span>: 0,
          <span class="hljs-string">"title"</span>: <span class="hljs-string">"Github"</span>,
          <span class="hljs-string">"extract"</span>: <span class="hljs-string">"Build software better, together"</span>
        }
      }
    ]
  }
}
</code></pre>
<p><strong>We’re only really interested in the title and extract of each page entry.</strong></p>
<p>So, let’s see how we can transform this document:</p>
<pre><code class="lang-bash">jq <span class="hljs-string">'.query.pages | [.[] | map(.) | .[] | {page_title: .title, page_description: .extract}]'</span> wikipedia.json
</code></pre>
<p>We’ll take a look at the command in more detail to understand it properly:</p>
<ul>
<li><p>First, we begin by accessing the pages array and passing that array into the next filter in the command via a pipe.</p>
</li>
<li><p>Then we iterate over this array and pass each object inside the pages array to the <em>map</em> function, where we simply create a new array with the contents of each object.</p>
</li>
<li><p><strong>Next, we iterate over this array and for each item create an object containing the two keys <em>page_title</em> and <em>page_description</em>.</strong></p>
</li>
<li><p>The <em>.title</em> and <em>.extract</em> references are used to populate the two new keys.</p>
</li>
</ul>
<p>This gives us a new, lean JSON structure:</p>
<pre><code class="lang-bash">[
  {
    <span class="hljs-string">"page_title"</span>: <span class="hljs-string">"Stack Overflow"</span>,
    <span class="hljs-string">"page_description"</span>: <span class="hljs-string">"Some interesting text about Stack Overflow"</span>
  },
  {
    <span class="hljs-string">"page_title"</span>: <span class="hljs-string">"Github"</span>,
    <span class="hljs-string">"page_description"</span>: <span class="hljs-string">"Build software better, together"</span>
  }
]
</code></pre>
<h2 id="heading-7-conclusion"><strong>7. Conclusion</strong></h2>
<p><strong>In this in-depth post, we reviewed some of the fundamental capabilities that jq provides for processing and modifying JSON from the command line.</strong></p>
<p>First, we looked at some of the most important filters that jq provides and how they may be used as the foundation for more complicated processes. Then we learned how to use the various built-in functions that come with JQ.</p>
<p>We finished with a difficult example that demonstrated how to convert one JSON document into another.</p>
<p><strong>Of course, check out the fantastic</strong> <a target="_blank" href="https://github.com/stedolan/jq/wiki/Cookbook"><strong>cookbook</strong></a> <strong>for additional fascinating examples</strong>, and as always, the article's full source code can be found <a target="_blank" href="https://github.com/OmkarKirpan/blog/tree/main/jq">on GitHub</a>.</p>
]]></content:encoded></item></channel></rss>