1

I want to create one function instead of several duplicate lines of code. I have this module. It`s works, but I want to optimize this code.

import React from 'react';

const form = (props) => {
    //start
    let arr = props.data.nodes.map((element) => element.vendor);
    let unique = arr.filter(function(elem, index, self) {
        return index === self.indexOf(elem);
    });
    let arr2 = props.data.nodes.map((element) => element.location);
    let unique2 = arr2.filter(function(elem, index, self) {
        return index === self.indexOf(elem);
    });
    let arr3 = props.data.nodes.map((element) => element.service);
    let unique3 = arr3.filter(function(elem, index, self) {
        return index === self.indexOf(elem);
    });
    let arr4 = props.data.nodes.map((element) => element.type);
    let unique4 = arr4.filter(function(elem, index, self) {
        return index === self.indexOf(elem);
    });
  //end
    return(
        <div className='wrapper'>
            <form>
                <label>
                    <p className="nameOfInput">Vendor</p>
                    <select onChange={props.filterOurData} >
                        <option>Choose vendor</option>
                        {unique.map((element) => <option  key={element.toString()}>{element}</option>)}
                    </select>
                </label>
                <label>
                    <p className="nameOfInput">Location</p>
                    <select onChange={props.filterOurLocation} >
                        <option>Choose location</option>
                        {unique2.map((element) => <option key={element.toString()}>{element}</option>)}
                    </select>
                </label>
                <label>
                    <p className="nameOfInput">Service</p>
                    <select onChange={props.filterOurService} >
                        <option>Choose service</option>
                        {unique3.map((element) => <option key={element.toString()}>{element}</option>)}
                    </select>
                </label>
                <label>
                    <p className="nameOfInput">Device Type</p>
                    <select onChange={props.filterOurDeviceType} >
                        <option>Choose device type</option>
                        {unique4.map((element) => <option key={element.toString()}>{element}</option>)}
                    </select>
                </label>
            </form>
        </div>
    );
}

export default form;

I want to optimize code from the "start" to the "end", but I can't figure out how.

Link to the my small app: https://github.com/DrGreenNow/Relate-data

2 Answers 2

2

I will suggest you to create a separate component for Select and pass all the relevant info to that component. That component will be responsible of filtering the data and rendering the ui elements.

Data that you need to pass to Select Component will be:

data: to render the options

filterKey: to filter out the data

label: default label for the select field

change: function to handle change

Like this:

const form = (props) => {
    return(
        <div className='wrapper'>
            <form>
                <Select label="Vendor" onChange={props.filterOurData} filterKey="vendor" data={props.data.nodes} />
                <Select label="Location" onChange={props.filterOurLocation} filterKey="location" data={props.data.nodes} />
                <Select label="Service" onChange={props.filterOurService} filterKey="service" data={props.data.nodes} />
                <Select label="Device Type" onChange={props.filterOurDeviceType} filterKey="type" data={props.data.nodes} />
            </form>
        </div>
    );
}


const Select = (props) => {
    let arr = props.data.map((element) => element[props.filterKey]);
    let unique = arr.filter((elem, index, self) => index === self.indexOf(elem));

    return (
        <label>
            <p className="nameOfInput">{props.label}</p>
            <select onChange={props.onChange} >
                <option>Choose {props.label}</option>
                {unique.map((element) => <option  key={element.toString()}>{element}</option>)}
            </select>
        </label>
    )
}
Sign up to request clarification or add additional context in comments.

2 Comments

This answer is better than mine, use this one
You give me an answer for my another problem in advance - about separate component for Select. Thanks!
1

I've attempted to simplify it a bit

    
    // setup dummy data
    let props = {
      data: {
      nodes: []
      }
    };
    for (let i = 0; i<10; i++) {
        let node = {
        vendor: "vendor"+ i,
        location: "location" + i,
        service: "service" + i,
        type: "type" + i
      }
    props.data.nodes.push(node)
    }
    
    //start
    let unique = []
    let unique2 = []
    let unique3 = []
    let unique4 = []
    
    props.data.nodes.map((element) => {
      unique.push(element.vendor)
      unique2.push(element.location)
      unique3.push(element.service)
      unique4.push(element.type)
    })
    //end
    
    console.log(unique)
    console.log(unique2)
    console.log(unique3)
    console.log(unique4)
    console.log(props.data.nodes)
    

One map -> 4 arrays of data

Comments

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.