1

I have a class component and its state contains a filterItems[] blank array. I need to populate the values inside the filterItems array

So, I have a data coming from API which looks something like this:

0:
emp_code: "a001"
company_code: "company_a"
keys: ["id", "post" ] 
dtypes: ["str", "int"]

1:
emp_code: "b001"
company_code: "company_b"
keys: ["sal", "name" ] 
dtypes: ["int", "str"]

//so on for other companies and employees

So, like this I have a few employees. Now I have to loop through this api data and extract the information and store it into another array called "filters" and pass it to a function.

My filter array should look something like this:

filters: [
        {
          key_name: "id",
          company_code: "company_a",
          input_type: "text",
          dtype: "str"
        },
        {
          key_name: "post",
          company_code: "company_a",
          input_type: "text",
          dtype: "int"
        },
//... keys for other company
]

essentially, I need to do the following in react

for each emp_code
  for each company_code
     for each key:
         keys[i]== filters.key_name
         company_code== filters.company_code
//...so on

The catch here is that, each company has a set of keys so if the employee belongs to the same company then I dont need to add again to the filter array. So, I basically need to check unique company_code and add the different types of keys a company has to the filters array.

2
  • why don't you add the data from api, instead of console log? Commented May 23, 2019 at 6:15
  • Is it the algorithm you are struggling with or where to do it in React so it makes sense? If you use a react from on 16.6, I think getDerivedStateFromProps might be an appropriate place to put your mapping Commented May 23, 2019 at 6:27

2 Answers 2

1

If I'm understanding you right, you want to filter your data like this:

Let's say you store your API data in a variable called myArr

Create a new variable called updatedArr that will map over myArr

const updatedArr = myArr.map((company, compIndex, compArr) => {
    return company.keys.map((key, keyIndex, keyArr) => {
        return {
            key_name: key,
            company_code: company.company_code,
            input_type: "text",
            dtype: company.dtypes[keyIndex]
        }
    })
}).reduce((acc, cur) => {
    return [...acc, ...cur]
}, [])

Then parse updatedArr to get the uniqueValues only

let uniqueValues = [];
//parses out duplicates
updatedArr.forEach(function(item) {
  //i will be 0 or more if there already is an item in our array, which means the current item we are iterating over is a duplicate
  var i = uniqueValues.findIndex(
    x => x.dtype == item.dtype && x.company_code == item.company_code
  );
  if (i <= -1) {
    //if item is not yet inside uniqueValues, add it to uniueValues
    uniqueValues.push(item);
  }
});

Then update your componentState with the uniqueValues

this.setState({
   filters: uniqueValues
})

Also created a sandbox to show you this working in-action: https://codesandbox.io/s/rendering-companies-ibs7g

Sign up to request clarification or add additional context in comments.

11 Comments

This works correct, can you also show how to check the uniqueness of the company. So basically if the company already exists I dont want it to add the company again.
@user8306074 Ohhhhh. So you only want to have the company added once, what do you do with the different keys and data-types then? Dont they need their own objects? The desired output you showed us has multiple of the same company_code, so its rather unclear what you want to make :/
So basically, I want to apply a filter on each company_code based on keys. So keys are the columns in my dataset and they are key identifiers of a company. So I want to apply any filtering based on the company_code and retrieve emp_code of those filters. Your code is working good. But it generates an output for each row. So If I have two employees of the same company then it will create two identical objects in the filters array. Thus, I want the company_code to be unqiue
So, If my array reads the same company_code again, reject it, and move to the next row. I guess we need an if condition to check this after the first map loop
Hmmm that's a possible solution. Right now we generate an object for each unique key in the company, which I think makes sense for how you want to consume this data. I think we actually need to configure your Table code so that it knows how to properly filter this data. That might be a separate question altogether though.
|
0

Assuming your data is a array.

    let filters = [];

    data.forEach(item => {
        item.keys.forEach(key => {
            item.dtypes.forEach(dtype => {
                const filter = {
                    key_name: key,
                    company_code: item.company_code,
                    input_type: "text",
                    dtype: dtype
                };
                filters.push(filter)
            })
        })
    });

2 Comments

So this will loop over each key and generate two outputs for different dtypes but in my state: key id has a dtype str and post has a dtype as int. So I need to loop over keys and dtypes at the same time
Yes. it is done in the above snippet. First Loop all the items on the outerLoop. Then loop all the keys, and loop all the dtypes in the innerLoop and create the new object and push it to the filters. Try this snippet and let me know your thoughts

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.