skip to Main Content

I have a array of objects like this

let input = [
    {
        "metadata": { "id": 1071, "name": "USA" },
        "accesories": [ { "name": "steel" } ]
    },
    {
        "metadata": { "id": 1068, "name": "China" },
        "accesories": [ { "name": "electronics" } ]
    },
]

Desired output:

["USA", "China"]

In order to get above result, I use the following

input.map((el) => el?.metadata?.name);

But if I want to filter first by electronics and based on which object has accessories with name as electronics in it, how do I achieve that result?

for e.g.

output: ["USA"] //if I want to filter by object which has name steel
output: ["China"] //if I want to filter by object which has name electronics

Can someone let me know how can I use filter with above map method?

2

Answers


  1. You can do this by first filtering the array based on the presence of the desired accessory name, and then mapping over the filtered array to extract the names like this.

    Use the filter() method to create an array with only the desired accessory.

    Use the map() method to extract the name

    let input = [
        {
            "metadata": { "id": 1071, "name": "USA" },
            "accesories": [ { "name": "steel" } ]
        },
        {
            "metadata": { "id": 1068, "name": "China" },
            "accesories": [ { "name": "electronics" } ]
        },
    ];
    const filterParameter = "electronics";
    
    const filteredObjects = input.filter(el => el?.accesories.some(acc => acc?.name === filterParameter));
    const result = filteredObjects.map(el => el?.metadata?.name);
    
    console.log(result);
    Login or Signup to reply.
  2. If you need a performant solution, avoid intermediate arrays and use Array#reduce():

    let input = [
        {
            "metadata": { "id": 1071, "name": "USA" },
            "accesories": [ { "name": "steel" } ]
        },
        {
            "metadata": { "id": 1068, "name": "China" },
            "accesories": [ { "name": "electronics" } ]
        },
    ];
    const name = "electronics";
    
    const result = input.reduce((r, item) => (item.accesories.some(acc => acc.name === name) && r.push(item.metadata.name), r), []);
    
    console.log(result);

    And a benchmark:

    ` Chrome/123
    -------------------------------------------------------------------------------------
    >                 n=2        |      n=20       |       n=200       |      n=2000     
    Alexander   ■ 1.00x x10m 347 | ■ 1.00x x1m 150 | ■ 1.00x x100k 117 | ■ 1.00x x10k 140
    Chris G       1.15x x10m 399 |   1.19x x1m 178 |   1.29x x100k 151 |   1.31x x10k 184
    -------------------------------------------------------------------------------------
    https://github.com/silentmantra/benchmark `
    
    let $chunk = [
        {
            "metadata": { "id": 1071, "name": "USA" },
            "accesories": [ { "name": "steel" } ]
        },
        {
            "metadata": { "id": 1068, "name": "China" },
            "accesories": [ { "name": "electronics" } ]
        },
    ];
    
    const $input = [], input = $input;
    
    const filterParameter = "electronics";
    
    // @benchmark Chris G
    const filteredObjects = input.filter(el => el?.accesories.some(acc => acc?.name === filterParameter));
    filteredObjects.map(el => el?.metadata?.name);
    
    // @benchmark Alexander
    input.reduce((r, item) => (item.accesories.some(acc => acc.name === filterParameter) && r.push(item.metadata.name), r), []);
    
    /*@skip*/ fetch('https://cdn.jsdelivr.net/gh/silentmantra/benchmark/loader.js').then(r => r.text().then(eval));
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search