Home > front end >  How to condense this script?
How to condense this script?

Time:09-11

I am currently using ReTool, an app-building platform that uses javascript. I generated a multi-select dropdown menu that I want to filter out a table. The {{multiselect1.value[i]}} indicate the selected values and value.Operation are the rows with conditions I want to keep. I am wondering if there is a more condensed form of this function that can handle as many selections as possible. This code only works for up to 6 selections.

function MultiSelect(value) {
  if ({{multiselect1.value[0] !== undefined}} && {{multiselect1.value[1] === undefined}}) {
    return value.Operation === {{multiselect1.value[0]}}
  }
  else if ({{multiselect1.value[1] !== undefined}} && {{multiselect1.value[2] === undefined}}) {
    return value.Operation === {{multiselect1.value[0]}} || value.Operation === {{multiselect1.value[1]}}
  }
  else if ({{multiselect1.value[2] !== undefined}} && {{multiselect1.value[3] === undefined}}) {
    return value.Operation === {{multiselect1.value[0]}} || value.Operation === {{multiselect1.value[1]}} || value.Operation === {{multiselect1.value[2]}}
  }
  else if ({{multiselect1.value[3] !== undefined}} && {{multiselect1.value[4] === undefined}}) {
    return value.Operation === {{multiselect1.value[0]}} || value.Operation === {{multiselect1.value[1]}} || value.Operation === {{multiselect1.value[2]}} || value.Operation === {{multiselect1.value[3]}}
  }
  else if ({{multiselect1.value[4] !== undefined}} && {{multiselect1.value[5] === undefined}}) {
    return value.Operation === {{multiselect1.value[0]}} || value.Operation === {{multiselect1.value[1]}} || value.Operation === {{multiselect1.value[2]}} || value.Operation === {{multiselect1.value[3]}} || value.Operation === {{multiselect1.value[4]}}
  }
  else if ({{multiselect1.value[5] !== undefined}} && {{multiselect1.value[6] === undefined}}) {
    return value.Operation === {{multiselect1.value[0]}} || value.Operation === {{multiselect1.value[1]}} || value.Operation === {{multiselect1.value[2]}} || value.Operation === {{multiselect1.value[3]}} || value.Operation === {{multiselect1.value[4]}} || value.Operation === {{multiselect1.value[5]}}
  }
  else {
    return value.Operation !== ""
  }
  };
return data.filter(MultiSelect);

CodePudding user response:

Edit: it looks like multiselect1.value is an array, so I think you can use the snippet at the bottom of this answer to really simplify things.


I'm not sure what multiselect1 is, so for example purposes I've simplified this using an array instead, and a string value for valueOperation, but this should provide a good starting point.

It looks like you're basically iterating over x items, and that can be done in a loop. All of your conditionals are checking current_value !== undefined && next_value === undefined), so you can do that by checking item [i] and [i 1].

Then, inside of your conditionals, you're checking all previous values and returning true if any match the operation, otherwise returning false. So once again we can do that in another loop (j=0; j<=i) to count up to and including the current i value that matched the conditional.

Lastly, if values match at all, return true. Otherwise, if the loop completes and none of the values matched, it returns false.

let multiselect1 = [
  'test1',
  'test2',
  'test3',
  'test4',
  'test5',
  'test6',
];

function filter(testarray, operation) {
  for (let i=0; i<=testarray.length; i  ) {
    // console.log('checking ' testarray[i] ' and ' testarray[i 1]);
    
    if (testarray[i] !== undefined && testarray[i 1] === undefined) {
      // console.log(i   ' matched the conditional');
      
      for (let j=0; j<=i; j  ) {
        if (operation === multiselect1[j]) {
          // console.log('same operation found at '   j);
          return true;
        }
      }
      return false; // no matches
    }
  }
  
  return false;
}

console.log(filter(multiselect1, 'test0'));
console.log(filter(multiselect1, 'test1'));
console.log(filter(multiselect1, 'test3'));
console.log(filter(multiselect1, 'test4'));
console.log(filter(multiselect1, 'test6'));
console.log(filter(multiselect1, 'test7'));

This first conditional logic seems to be finding the max/last item. In a native JavaScript array, this is easy without needing a loop or this conditional logic because indexOf() exists. And at that point, you don't even need to use a custom function.

let multiselect1 = [
  'test1',
  'test2',
  'test3',
  'test4',
  'test5',
  'test6',
];

function filter(testarray, operation) {
  return testarray.indexOf(operation) !== -1;      
}

console.log(filter(multiselect1, 'test0'));
console.log(filter(multiselect1, 'test1'));
console.log(filter(multiselect1, 'test3'));
console.log(filter(multiselect1, 'test6'));
console.log(filter(multiselect1, 'test7'));

// can do this in one line instead of needing the filter function
console.log(multiselect1.indexOf('test0') !== -1);
console.log(multiselect1.indexOf('test1') !== -1);
console.log(multiselect1.indexOf('test3') !== -1);
console.log(multiselect1.indexOf('test6') !== -1);
console.log(multiselect1.indexOf('test7') !== -1);

CodePudding user response:

As per my understanding, You have multiselect values and an operation value and you are trying to match if that operation value exist in the multiselect values array. If Yes, you can simply achieve that by just using an Array.includes() method.

Live Demo :

const multiselect1 = {
 value: ['Operation 1', 'Operation 2', undefined, 'Operation 3', undefined, undefined, 'Operation 4', undefined, 'Operation 5']
};

const value = {
  operation: 'Operation 3'
};

function MultiSelect(value) {
  return multiselect1.value.includes(value.operation);
}

console.log(MultiSelect(value));

  • Related