What is the best way to separate multiline cells into arrays in Google Sheets?

Keeping track of the comics I've read can be a bit challenging, especially when some titles have issue numbers spread across multiple lines. Take for example the Avengers series that began in 2016 - here are the issue numbers listed in one cell:

#1-11
#1.1-5.1
#1MU
#672-676

To automatically calculate the total count of issues for each title, I attempted to write a script using regular expressions to extract and sum up the numbers. However, I'm encountering difficulties in correctly parsing the data and updating the counts as new issue numbers are added.

This is what I've come up with so far:

function calcIssueCount(x) {
  // Initializing the count:
  var issueCount = 0;
  // Creating an array from the lines in the cell:
  var box = x.split("\n");
  for (var line in box) {
    // Checking if there's a range of issue numbers:
    if ("-" in line === True) {
      // Removing unnecessary characters from the string:
      line = line.replace("#","");
      // Extracting the start and end numbers of the range:
      var a = line.match(/[0-9}+\.|[0-9]+-/);
      a = a.replace("-","");
      var b = line.match(/-[0-9}+\.|[0-9]+/);
      b = b.replace("-","");
      // Converting extracted numbers into integers:
      a = parseInt(a)
      b = parseInt(b)
      // Calculating the number of issues within the range:
      var c = b - a + 1;
      // Updating the total issue count:
      issueCount += c;
    }
    else {
      // If no range is found, consider it as a single issue:
      issueCount += 1;
    }
}
}

Function calcIssueCount(x) should be called with the cell name (e.g., D15).

I suspect there might be mistakes in my approach, particularly in handling the cell data and converting it into an array. Can you point out where I may be going wrong?

Answer №1

To extract the value "22" from a cell, here is the logic I followed:

#1-11
#1.1-5.1
#1MU
#672-676

Based on this understanding, the steps to retrieve "22" are as follows:

  • Take out 1 and 11 from #1-11.
  • Extract 1.1 and 5.1 from #1.1-5.1.
  • Get 672 and 676 from #672-676.
  • Difference between the numbers in each line.
  • Add 1 to each result.
  • If there is no range indicated by '-', just add 1.

By applying the above logic, you can obtain the value of "22" through the following calculation:

(11 - 1 + 1) + (5.1 - 1.1 + 1) + (1) + (676 - 672 + 1)
. If my interpretation aligns with your requirement, consider making these modifications:

Proposed Changes :

  • Use box[line] instead of for (var line in box) { to access elements individually.
    • For this purpose, switch to using forEach.
  • In JavaScript, differentiate between boolean expressions "true" and "false".
  • Since line isn't an object, avoid errors like "-" in line by using indexOf().
    • This adjustment will prevent potential issues.
  • Use Number() over number() for numerical operations in JavaScript.
  • Ensure that your custom function calcIssueCount(x) returns values for proper functioning according to your script.
  • The functionality of line(/[0-9}+\.|[0-9]+-/) wasn't clear to me; apologies for any confusion caused.

In my revised version, I employed the regex ([0-9.]+)-([0-9.]+) to capture both before and after numbers efficiently. Keep in mind that there could be multiple solutions applicable to your scenario. This modification provides one approach among many available options.

Enhanced Script :

Pattern 1 :

The original script was adjusted in this pattern.

function calcIssueCount(x) {
  var issueCount = 0;
  var box = x.split("\n");
  box.forEach(function(e){
    if (e.indexOf("-") > -1) {
      var numbers = e.match(/([0-9.]+)-([0-9.]+)/);
      var a = Number(numbers[1]);
      var b = Number(numbers[2]);
      var c = b - a;
      c += 1;
      issueCount += c;
    } else {
      issueCount += 1;
    }
  });
  return issueCount;
}
Pattern 2 :

An alternative script without regex usage yielding equivalent results to Pattern 1.

function calcIssueCount(x) {
  return x.split("\n").reduce(function(c, e) {
    if (e.indexOf("-") > -1) {
      var numbers = e.slice(1).split("-");
      c += (Number(numbers[1]) - Number(numbers[0])) + 1;
    } else {
      c += 1;
    }
    return c;
  }, 0);
}

Outcome :

https://i.sstatic.net/flYnH.png

Note :

  • I utilized the regex ([0-9.]+)-([0-9.]+) specifically for the provided sample. For different patterns, additional samples would assist in tailoring the solution accordingly.

References :

If my interpretation differs from your intention, kindly accept my apologies for any confusion caused.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Issue encountered with Ionic and ssh2: process.binding is not supported

I am currently delving into the world of Ionic and experimenting with creating a basic application that utilizes SSH2 to establish an ssh connection between the app and a server. Here is a breakdown of the steps I took to encounter the issue: Steps to Rep ...

Creating an ngInclude directive on the fly: A step-by-step guide

Whenever I insert this into my HTML, everything functions correctly: <div ng-include="'my-template.html'"></div> However, when attempting to dynamically create that ngInclude directive using jQuery (after the DOM has loaded), it fai ...

Issue: After upgrading jQuery, the .on() method and document.ready event are not functioning properly when used in conjunction

After browsing through other solutions on StackOverflow, I am left wondering why this code suddenly stopped working. Here's some context... we are still sticking with jQuery 1.7.1 and trying to fix plugins and pages that are not compatible with the ne ...

AngularJS allows users to easily navigate to the next and previous days, years, and

With Angular's date filter, I can easily retrieve the current day, year, and month using $filter. However, is there a way to access the next and previous days, years, and months as well? I attempted to write this code but I'm unsure of how to p ...

I am in the process of transforming my basic JS Array into one that contains key/value

Currently, I am utilizing jQuery to create an Array in the following manner: var arr = new Array(); $('#some-form .some-input').each(function() { arr.push($(this).val()); ...

Ways to manually conceal a popover using Bootstrap 5

I am attempting to generate multiple Bootstrap popover instances that can all be closed with a single click. Here is the approach I took: document.addEventListener('DOMContentLoaded', function () { var items = []; document.getElementBy ...

If you don't get the correct response from the $.ajax success function

I am utilizing the $.ajax function to retrieve content, however I am encountering an issue when attempting to display special tags from it. The data appears to be missing! This is how I am currently handling it: $(document).ready(function(){ $("button") ...

How can I implement a for loop in Node.js?

I am currently experiencing an issue with my for loop while attempting to retrieve data from MongoDB and display it in the browser. The problem is that it only iterates through once, resulting in only the first entry being output. Strangely enough, when ...

Retrieve the initial occurrence that meets the conditions across three columns in MySQL

I am currently utilizing a NodeJS REST API that connects to a MySQL database. Within this database, there is a specific table we will refer to as Table_01: | C_0| C_1| C_2| C_3| | 1 | A1 | B1 | 1 | | 2 | A1 | B2 | 0 | | 3 | B1 | A1 | 0 | | 4 | A2 | ...

What is the process for packaging asset folders in an Angular 4 application?

Currently, in my Angular4 App with Webpack, after executing the ng-build --prod command to build the application, I noticed that while the assets folder is present in the dist directory, the css and js files are not bundled or minified. I am seeking guida ...

Encountered a 404 error (not found) while making a GET request with axios

I encountered an issue with my pizza shop application built with Next.js. Whenever I run the app on my computer, I come across this error: https://i.sstatic.net/tsQzZ.png The error disappears after refreshing the page. Here is my index.js file: import ax ...

What is the best way to link assets within an Angular custom element (Web Components)?

After successfully creating a web component and referencing an image from my asset folder, everything was running smoothly on my local environment. However, when I published my custom element to Firebase hosting, I encountered some issues. When trying to ...

Loading an HTML file conditionally in an Angular 5 component

Consider a scenario in my project where I have a testDynamic component. @Component({ templateUrl: "./test-dynamic.html", // This file needs to be overriden styleUrls: ['./test-dynamic.css'] }) export class testDynamic { constructor() ...

Oops! The Route post function is missing some necessary callback functions, resulting in an undefined object error

I need to verify if a user has admin privileges. Every time I try calling the verifyAdminUser function from my router, I encounter the following error: Error: Route.post() requires callback functions but got a [object Undefined] at Route.(anonymous func ...

Guide to automatically remove Mongoose document after a specified time period of either 5 seconds or one day

Can someone help me with deleting a document after either a day or 5 seconds? Here is a basic Schema I am working with: import mongoose from 'mongoose'; const schema = new mongoose.Schema({ id: {type: String, required: true}, // yelp id ...

Loop through the elements of one array using the indexes from a second array

Hey there! I need help with the following code snippet: let names = ["josh", "tony", "daniel"]; let arrayplaces = ["30", "60", "90"]; names.forEach((elem, indexed) => { const num2 = arrayp ...

What is the best way to distinguish between the paths for administrators and regular users?

Currently, I am in the process of setting up routes using node js for a dashboard. Firstly, users will need to log in to obtain a JWT token. With the Token, users can access various user-related routes such as editing, deleting, and logging out. However, ...

Troubleshooting issues with node debugger

Looking for a nodeJS alternative to ruby's binding.pry has been quite the challenge, but I'm determined to find a solution. I created a file called testDebugger.js with the following content: var x = 10; debugger; var y = 5; Upon running the c ...

Incorporating external JavaScript into a Rails application

Having trouble with the syntax on this simple problem. Struggling to find examples of externally linked files, all solutions online involve storing a local copy instead. <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js" typ ...

The webpage displays the element as <span class="icon">&#xe80d;</span> instead of rendering it properly

In my ReactJS project, I have created a component called Menu1item: class Menu1item extends React.Component{ render(){ return ( <div> {this.props.glyph}{this.props.value} </div> ) ...