0

I have two arrays:

countriesArr:

  [
      {
        "countryCode": "DEU",
        "name": "Germany",
        "companyFunctions": [
          {
            "name": "E-Commerce",
            "companyName": "Company 1"
          }
        ]
      },
      {
        "countryCode": "FRA",
        "name": "France",
        "companyFunctions": [
          {
            "name": "Shopping Centre",
            "companyName": "Company 1"
          },
          {
            "name": "Support Services",
            "companyName": "Company 2"
          },
          {
            "name": "Procurement Support",
            "companyName": "Company 3"
          },
          {
            "name": "Retail",
            "companyName": "Company 3"
          }
        ]
      }
    ]

and filterArr:

[
    {
        "name": "Company 2", 
        "id": "32434d324-32434"
    },
    {
        "name": "Company 3", 
        "id": "2643d3254-39244"
    }
]

What I want to do is filter the countriesArr by looping through the countriesArr array where countriesArr.companyFunctions.companyName === filterArr.name.

I wrote the following code:

countriesArr.filter(p =>
    p.companyFunctions.filter(cF =>
        filterArr.filter(c => c.name === cF.companyName)
    )
); 

But this doesn't seem to work as it returns also the German object from countriesArr and it includes Company 1 in the companyFunctions of the French object from countriesArr while Company 1 isn't in the filterArr.

What am I doing wrong?

The desired result should look like:

[
  {
    "countryCode": "FRA",
    "name": "France",
    "companyFunctions": [
      {
        "name": "Support Services",
        "companyName": "Company 2"
      },
      {
        "name": "Procurement Support",
        "companyName": "Company 3"
      },
      {
        "name": "Retail",
        "companyName": "Company 3"
      }
    ]
  }
]
3
  • 1
    .filter() always returns an array. And every array (empty or not) is always truthy Commented Jul 20, 2020 at 14:28
  • please add the wanted result. Commented Jul 20, 2020 at 14:28
  • @NinaScholz I have updated the question with the desired result. Commented Jul 20, 2020 at 14:31

4 Answers 4

2

You could rebuild a new object if companyFunctions contains the wanted names.

This approach take a hash table for wanted names where the property is true. This allows to filter later just with the destructured property companyName and a simple call of the property of names.

Finally, if the filteres array has a truthy (any other value except zero) length, take this array along with the rest of the object and pus a new object to the result set.

const
    countriesArr = [{ countryCode: "DEU", name: "Germany", companyFunctions: [{ name: "E-Commerce", companyName: "Company 1" }] }, { countryCode: "FRA", name: "France", companyFunctions: [{ name: "Shopping Centre", companyName: "Company 1" }, { name: "Support Services", companyName: "Company 2" }, { name: "Procurement Support", companyName: "Company 3" }, { name: "Retail", companyName: "Company 3" }] }],
    filterArr = [{ name: "Company 2", id: "32434d324-32434" }, { name: "Company 3", id: "2643d3254-39244" }],
    names = filterArr.reduce((r, { name }) => (r[name] = true, r), {}),
    result = countriesArr.reduce((r, { companyFunctions, ...o }) => {
        companyFunctions = companyFunctions.filter(({ companyName }) => names[companyName]);
        if (companyFunctions.length) r.push({ ...o, companyFunctions });
        return r;
    }, []);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

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

1 Comment

I would like to accept your answer could you briefly explain what is happening? It's very daunting to read.
2

const countriesArr = [
    {
        countryCode: 'DEU',
        name: 'Germany',
        companyFunctions: [
            {
                name: 'E-Commerce',
                companyName: 'Company 1',
            },
        ],
    },
    {
        countryCode: 'FRA',
        name: 'France',
        companyFunctions: [
            {
                name: 'Shopping Centre',
                companyName: 'Company 1',
            },
            {
                name: 'Support Services',
                companyName: 'Company 2',
            },
            {
                name: 'Procurement Support',
                companyName: 'Company 3',
            },
            {
                name: 'Retail',
                companyName: 'Company 3',
            },
        ],
    },
];

const filterArr = [
    {
        name: 'Company 2',
        id: '32434d324-32434',
    },
    {
        name: 'Company 3',
        id: '2643d3254-39244',
    },
].map((f) => f.name);

const result = countriesArr
    .map((c) => ({
        ...c,
        companyFunctions: c.companyFunctions.filter((cf) => filterArr.includes(cf.companyName)),
    }))
    .filter((c) => c.companyFunctions.length > 0);

console.log(result);

Comments

1

What you want is not a filter over countriesArr but a map() (to transform it) and then a filter() (to remove entries with 0 companyFunctions) or vice-versa (first filter() those having at least one matching companyFunction and then map to transform removing unwanted ones). But mapping and then filtering seems more straightforward to me...

const result = countriesArr                                                 
    .map(function(ca) {                                                     
        ca.companyFunctions = ca.companyFunctions.filter(                   
                cf => filterArr.some(fa=>fa.name==cf.companyName)           
        );                                                                  
        return ca;                                                          
    })                                                                      
    .filter(ca=>ca.companyFunctions.length)                                 
;                                                                           
                                                                            
console.log(JSON.stringify(result, null, 4));                               
// [                                                                        
//     {                                                                    
//         "countryCode": "FRA",                                            
//         "name": "France",                                                
//         "companyFunctions": [                                            
//             {                                                            
//                 "name": "Support Services",                              
//                 "companyName": "Company 2"                               
//             },                                                           
//             {                                                            
//                 "name": "Procurement Support",                           
//                 "companyName": "Company 3"                               
//             },                                                           
//             {                                                            
//                 "name": "Retail",                                        
//                 "companyName": "Company 3"                               
//             }                                                            
//         ]                                                                
//     }                                                                    
// ] 

Comments

0

var countriesArr = [{
    "countryCode": "DEU",
    "name": "Germany",
    "companyFunctions": [{
      "name": "E-Commerce",
      "companyName": "Company 1"
    }]
  },
  {
    "countryCode": "FRA",
    "name": "France",
    "companyFunctions": [{
        "name": "Shopping Centre",
        "companyName": "Company 1"
      },
      {
        "name": "Support Services",
        "companyName": "Company 2"
      },
      {
        "name": "Procurement Support",
        "companyName": "Company 3"
      },
      {
        "name": "Retail",
        "companyName": "Company 3"
      }
    ]
  }
];

var filterArr = [{
    "name": "Company 2",
    "id": "32434d324-32434"
  },
  {
    "name": "Company 3",
    "id": "2643d3254-39244"
  }
]

console.log(countriesArr.filter(item => {
  return filterArr.findIndex(company => item.companyFunctions.some(d => d.companyName === company.name)) != -1
}))

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.