0

I have some loop like this

for (let i = 0, l = this.documents.length; i < l; ++i) {
  if (item.text !== null) {
    if (this.documents[i].text === item.text) {
      this.documents[i].mandatory = !item.mandatory;
      break;
    }
  } else {
    if (this.documents[i].code === item.code) {
      this.documents[i].mandatory = !item.mandatory;
      break;
    }
  }
}

The problem I have is that I have code smell, with so many if, else, can somebody help me to make it shorter and reusable? Thanks

3
  • Hi, please priovide example input and output. Would be best if you could create small snippet. Commented May 17, 2021 at 8:18
  • Side note: l = this.documents.length is not a useful optimisation since about IE7 or 8. Browsers and engines should already implement this for you. Commented May 17, 2021 at 8:19
  • Are you sure this is not a schoolwork? Commented May 17, 2021 at 8:29

4 Answers 4

1

I'd write it like this:

let doc  = (item.text !== null)
    ? this.documents.find(d => d.text === item.text)
    : this.documents.find(d => d.code === item.code)

 if (doc)
      doc.mandatory = !item.mandatory
Sign up to request clarification or add additional context in comments.

Comments

0

You only need one if/else for this

It seems all of those if/else branches are setting the same value. So you only need one if statement.

for (let i = 0, l = this.documents.length; i < l; ++i) {
  if (!item.code && this.documents[i].text === item.text || item.code && this.documents[i].code === item.code) {
    this.documents[i].mandatory = !item.mandatory;
    break;
  }
}

Maybe a little more readable, but a very tiny bit slower in execution:

for (let i = 0, l = this.documents.length; i < l; ++i) {
  var hasItemText = !item.code && this.documents[i].text === item.text;
  var hasItemCode = item.code && this.documents[i].code === item.code;

  if ( hasItemText || hasItemCode ) {
    this.documents[i].mandatory = !item.mandatory;
    break;
  }
}

Comments

0

Because we don't know what output you expect it's hard to help you. But maybe like this?

const key = item.text ? "text" : "code";
const documentIndex = this.documents.findIndex((cur) => cur[key] === item[key]);
if(documentIndex > -1) this.documents[documentIndex].mandatory = !item.mandatory;

5 Comments

The expected output is mutation of the first matching document.
How should you know? You're not the author. The example code is clearly updating the documents array based of the unknown item.
No, the documents array itself stays intact. Only a single property of a single document in the array is updated.
Oh yeah, overread the break vor some reason. But in case the author wants an updated array, I edited my post.
Fails if no matching document is found.
0

You could store the key in advance.

Inside the loop, only a single if statement is required to check if a certain value match.

This approach takes the given loop because of unknown this.documents, which could be an array like object. Any other array method, like find needs an array and a conversion to it if not given.

const key = item.text !== null ? 'text' : 'code';

for (let i = 0, l = this.documents.length; i < l; ++i) {
    if (this.documents[i][key] === item[key]) {
        this.documents[i].mandatory = !item.mandatory;
        break;
    }
}

1 Comment

@loop, sorry i do not understand.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.