Can
Can

Reputation: 693

How to simplify this code to make the complexity low?

The code below has a large complexity because of lot if statements. How can I simplify this part of the code?

Will the code simplified when I change the latest else if to a else statement without conditions? And will it work on the same way?

parse(value: string): NgbDateStruct {
  if (value) {
    const date = value.trim().split('-');
    if (date.length === 1 && isNumber(date[0])) {
      return {
        year: toInteger(date[0]),
        month: undefined as any,
        day: undefined as any
      };
    } else if (date.length === 2 && isNumber(date[0]) && isNumber(date[1])) {
      return {
        year: toInteger(date[1]),
        month: toInteger(date[0]),
        day: undefined as any
      };
    } else if (date.length === 3 && isNumber(date[0]) && isNumber(date[1]) && isNumber(date[2])) {
      return {
        year: toInteger(date[2]),
        month: toInteger(date[1]),
        day: toInteger(date[0])
      };
    }
  }
  return undefined as any;
}

Upvotes: 0

Views: 89

Answers (2)

Henry Trần
Henry Trần

Reputation: 1391

Well, your code so simple in think, but it so long!!

if you want example, i have javascript vanilla code for do that:

function parse (value) {
    var list = (value + "").trim().split("-").reverse();
    if (list != 0 && list.every(x => !isNaN(x))) {
        return {
            year: parseInt(list[0]),
            month: parseInt(list[1]) || undefined,
            day: parseInt(list[2]) || undefined,
        }
    }
    return undefined;
}
// below for testing
[
    "08-11-2020",
    "11-2020",
    "2020",
    ""
].forEach(x => {console.log(x, parse(x))});

Unfortunately I don't have any experience implementing typescript code, but the above javascript code probably helps you out a bit. Actually I shorten the code because of advantages (disadvantages?) that javascript brings, maybe convert to typescript won't make much difference !!


additional typescript code:

On typescriptlang.org

type NgbDateStruct = {
    year?: number;
    month?: number;
    day?: number;
};

function parse (value: string) : NgbDateStruct {
    var list = (value + "").trim().split("-").reverse().map(x => x || -1).map(Number);
    if (list.length > 0 && list.every(x => !isNaN(Number(x))) && list.every(x => x > -1)) {
        return {
            year: list[0] || undefined,
            month: list[1] || undefined,
            day: list[2] || undefined,
        }
    }
    return undefined as any;
}
// below for testing
[
    "08-11-2020",
    "11-2020",
    "2020",
    "",
    "nothing"
].forEach(x => {console.log(x, parse(x))});

Upvotes: 1

CertainPerformance
CertainPerformance

Reputation: 370609

One option would be to use a regular expression to match digits, possibly interspersed with -s:

const getDateObj = value => {
  const match = value.match(/(^\d+)(?:-(\d+)(?:-(\d+))?)?$/);
  if (!match) return undefined;
  const [, first, second, third] = match.filter(group => group !== undefined).map(Number);
  if (third) {
    // All were matched
    return {
      year: third,
      month: second,
      day: first
    };
  } else if (second) {
    // Only first two were matched
    return {
      year: second,
      month: first
    }
  }
  return {
    year: first
  }
};

console.log(getDateObj('31-12-2000'));
console.log(getDateObj('12-2000'));
console.log(getDateObj('2000'));
console.log(getDateObj('incorrect'));

In TypeScript syntax:

type NgbDateStruct = {
    year: number;
    month?: number;
    day?: number;
};
const getDateObj = (value: string): NgbDateStruct | undefined => {
    const match = value.match(/(^\d+)(?:-(\d+)(?:-(\d+))?)?$/);
    if (!match) return undefined;
    const [, first, second, third] = match.filter(group => group !== undefined).map(Number);
    if (third) {
        // All were matched
        return {
            year: third,
            month: second,
            day: first,
        };
    }
    if (second) {
        // Only first two were matched
        return {
            year: second,
            month: first,
        };
    }
    return {
        year: first,
    };
};

Upvotes: 1

Related Questions