8

I have an array of objects,
From which I want to conditionally create another array of objects.

Eg. -

var devs = [
    {
        name: 'A',
        age: 26,
        tech: ['JavaScript','React'],
        addr:{
            country:'India',
            city:'Pune'
        }
    },
    {
        name: 'B',
        age: 25,
        tech: ['Node','AngularJs'],
        addr:{
            country:'USA',
            city:'NY'
        }
    },
    {
        name: 'C',
        age: 27,
        tech: ['React','AWS'],
        addr:{
            country:'UK',
            city:'London'
        }
    }
]

I want an Array of objects who have 'React' in their 'tech' field array,
And only want to display their Name and Tech,
The following is the expected output -

[
    {
        name: 'A',
        tech: ['JavaScript','React']
    },
    {
        name: 'C',
        tech: ['Java','React'],
    }
]

I know for conditional purpose filter method can be used,
But how do I leave out the unnecessary fields from the array of objects?
Can map method be used here? If so how do I implement it?

Following is my half cooked code -

var filteredDevs = devs.filter(temp => temp.tech.includes('React'));
6
  • regenerate your array Commented Mar 2, 2019 at 17:36
  • 2
    As you guessed in your title, yes you should use map. Have you tried it? Commented Mar 2, 2019 at 17:37
  • 1
    where do you get 'React' from 'C'? Commented Mar 2, 2019 at 17:38
  • @Bergi I knew it had to be used, but didn't know how to implement on object array, still learning :D Commented Mar 2, 2019 at 17:41
  • 1
    @AniruddhaRaje Write a function that can take one of these objects and returns a new object of the desired shape. Then pass that function to map Commented Mar 2, 2019 at 17:43

5 Answers 5

11

You can use Array.filter and Array.map to do it, filter using the Array.includes where you check for the presence of React in the tech array.

Second step is to map to the desired object by retaining only name and tech properties from the original object.

const devs = [{"name":"A","age":26,"tech":["JavaScript","React"],"addr":{"country":"India","city":"Pune"}},{"name":"B","age":25,"tech":["Node","AngularJs"],"addr":{"country":"USA","city":"NY"}},{"name":"C","age":27,"tech":["Java","AWS"],"addr":{"country":"UK","city":"London"}}];
const devReact = devs.filter(obj => obj.tech.includes("React")).map(obj => ({"name":obj.name, "tech":obj.tech}));
console.log(devReact);


You can also do it in one shot using Array.reduce, where you accumulate only those objects having React in the array.

const devs = [{"name":"A","age":26,"tech":["JavaScript","React"],"addr":{"country":"India","city":"Pune"}},{"name":"B","age":25,"tech":["Node","AngularJs"],"addr":{"country":"USA","city":"NY"}},{"name":"C","age":27,"tech":["Java","AWS"],"addr":{"country":"UK","city":"London"}}];
const devReact = devs.reduce((acc, ele) =>  ele.tech.includes("React") ? acc.concat({"name": ele.name, "tech":ele.tech}): acc ,[]);
console.log(devReact);

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

Comments

5

I will better use Array.reduce() for this task, to loop only once over the input data.

var devs = [
    {
        name: 'A',
        age: 26,
        tech: ['JavaScript','React'],
        addr: {country:'India', city:'Pune'}
    },
    {
        name: 'B',
        age: 25,
        tech: ['Node','AngularJs'],
        addr: {country:'USA', city:'NY'}
    },
    {
        name: 'C',
        age: 27,
        tech: ['React','AWS'],
        addr: {country:'UK', city:'London'}
    }
];

let res = devs.reduce((acc, {name, tech}) =>
{
    tech.includes("React") && acc.push({name, tech});
    return acc;
}, []);

console.log(res);
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}

Comments

2

You can use Array.prototype.map() to remove unnecessary fields

var devs = [
    {
        name: 'A',
        age: 26,
        tech: ['JavaScript','React'],
        addr:{
            country:'India',
            city:'Pune'
        }
    },
    {
        name: 'B',
        age: 25,
        tech: ['Node','AngularJs'],
        addr:{
            country:'USA',
            city:'NY'
        }
    },
    {
        name: 'C',
        age: 27,
        tech: ['Java','AWS'],
        addr:{
            country:'UK',
            city:'London'
        }
    }
]

let newArr =devs.filter(temp => temp.tech.includes('React')).map(({name,tech}) => ({name,tech}));
console.log(newArr);

Comments

2

You can use the filter + map functions, however that approach uses two loops for doing what you want.

This alternative uses the function reduce to generate the desired output

var devs = [    {        name: 'A',        age: 26,        tech: ['JavaScript','React'],        addr:{            country:'India',            city:'Pune'        }    },    {        name: 'B',        age: 25,        tech: ['Node','AngularJs'],        addr:{            country:'USA',            city:'NY'        }    },    {        name: 'C',        age: 27,        tech: ['React','AWS'],        addr:{            country:'UK',            city:'London'        }    }],
    result = devs.reduce((a, {name, tech}) => {
      if (tech.includes('React')) a.push({name, tech});
      return a;
    }, []);

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

Comments

1

You could filter and map the wanted properties.

var devs = [{ name: 'A', age: 26, tech: ['JavaScript', 'React'], addr: { country: 'India', city: 'Pune' } }, { name: 'B', age: 25, tech: ['Node', 'AngularJs'], addr: { country: 'USA', city: 'NY' } }, { name: 'C', age: 27, tech: ['React', 'AWS'], addr: { country: 'UK', city: 'London' } }],
    result = devs
        .filter(({ tech }) => tech.includes('React'))
        .map(({ name, tech }) => ({ name, tech }));

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.