221b
221b

Reputation: 431

How to get a particular attribute from an array of array objects?

I have an Array of Arrays, and each Array consists of objects. Here is a simplified version of what I'm referring to (it is a console.log of my original array) -

Array - [Array(2), Array(3), Array(2)]

Each Array has objects in the following format (taking the first array from above) -

Array(2) - 
0: {name: "test", score:40, date: "2018-09-18T00:00:00.000Z"}
1: {name: "test2", score:50 date: "2018-09-18T00:00:00.000Z"}

The other arrays are similar with the same attributes and different values.

I am trying to fetch the name attribute from each of these objects. I tried the below code - but I end up getting an undefined value:

const test1= array1.map(x=> x.values) // this gives me the array of arrays
const test2 = test1.map(function(y){return y.name})// this is my attempt to get the 'name' attribute from all of the arrays that include the objects.

What am I missing out on here? Is there a better way to get the attribute using arrow functions?

Upvotes: 5

Views: 15089

Answers (8)

Xiangming Hu
Xiangming Hu

Reputation: 355

Adding to Koushik's example, with ES2019, you can use flat() to flatten nested arrays:

const array = [[{name: 'test1'}, {name: 'test2'}], [{name: 'test3'}, {name: 'test4'}]]
var res = array.flat().map( ({name}) => name );
console.log(res);

Or if you have deeper levels:

const array = [[[{name: 'test1'}], {name: 'test2'}], [{name: 'test3'}, {name: 'test4'}]]
var res = array.flat(2).map( ({name}) => name );
console.log(res);

And so on.

Upvotes: 0

Mohammed Ashfaq
Mohammed Ashfaq

Reputation: 3426

/* TEST DATA */
array1 = [
  { name: 'test1', score: 40, date: '2018-09-18T00:00:00.000Z' },
];
array2 = [
  { name: 'test4', score: 50, date: '2018-09-18T00:00:00.000Z' },
  { name: 'test5', score: 40, date: '2018-09-18T00:00:00.000Z' }, 
];
array3 = [
  { name: 'test6', score: 50, date: '2018-09-18T00:00:00.000Z' },
  { name: 'test7', score: 50, date: '2018-09-18T00:00:00.000Z' },
  { name: 'test8', score: 40, date: '2018-09-18T00:00:00.000Z' },
  { name: 'test9', score: 50, date: '2018-09-18T00:00:00.000Z' },
];

testResults = [array1, array2, array3];

// Solution 

function getListOfName(){
  let names = [];
  testResults.map(testResult => {
    testResult.map(({name}) => {if(name) names.push(name)})
  })
  return names;
}
console.log("Full list of names", getListOfName());

// If you want to restrict to K names from each array
function getFirstKNamesfromArray(limit){
  let names = [];
  testResults.map(testResult => {
    testResult.map(({name}, index) => {
      if(name && (index < limit)) names.push(name)
    })
  })
  return names
}
console.log("First 2 names from each array", getFirstKNamesfromArray(2));

Upvotes: 3

aagrawal
aagrawal

Reputation: 1

const test1= array1.map(x=> x.values)

This is returning undefined.

let requiredArr = [];

let array1 = [Array(2), Array(3), Array(2)]

let test2 = array1.map(x => x.map(y => requiredArr(y.name));

test2 will give the desired result.

Upvotes: 0

Koushik Chatterjee
Koushik Chatterjee

Reputation: 4175

Flatten it, and map it to names or Vise versa

First flatten it, and map

const array = [[{name: 'test1'}, {name: 'test2'}], [{name: 'test3'}, {name: 'test4'}]]

var res = [].concat(...array).map(({name})=>name);
console.log(res);

Now, map it to names and then flatten

const array = [[{name: 'test1'}, {name: 'test2'}], [{name: 'test3'}, {name: 'test4'}]]

var res = [].concat(...array.map(a=>a.map(b=>b.name)))
console.log(res);

Now, In this one, certainly you can notice that we are actually mapping it in each level (we have to, no other way with first map only approach. so we can perform a reduce in place of the outer map and concat it there itself, so we can avoid the outer concat (for flatten) and inner concat will actually flatten it. Here we go:

const array = [[{name: 'test1'}, {name: 'test2'}], [{name: 'test3'}, {name: 'test4'}]]

var res = array.reduce((r, a)=>r.concat(a.map(b=>b.name)), []);
console.log(res);

Upvotes: 11

Charlie
Charlie

Reputation: 183

Take into account that map returns an array; you iterate over it. Filter or reduce do the same.

const test1= array1.map(x=> x.values) // x doesn't have a property named  "value"
//simply use forEach
array1.forEach((el) => console.log(el.name))

If you want to capture the names inside a collection:

const let container = [];
array1.forEach((el) => container.push(el.name))

A good way to better understand this iterator functions would be to first use loops and then attempt to "translate" your code into one of them.

Upvotes: 2

H.P.
H.P.

Reputation: 86

Here:

const arr = [
    [{name: 'a', date:'x'}, {name: 'b', date:'y'}],
    [{name: 'c', date:'x'}, {name: 'd', date:'y'}]
];

const names = arr.map(el => el.map(obj => obj.name));

console.log(names.join());
console.log(names.flat());

you can use flat() to keep names in an array or join() to merge the names into a string.

Upvotes: 0

Bernardo Siqueira
Bernardo Siqueira

Reputation: 414

This should work fine. You need to flatten the array structure and map the names.

const array = [[{name: 'test1'}, {name: 'test2'}], [{name: 'test3'}, {name: 'test4'}]]

const names = array.reduce((acc, innerArray) => {
  return [...acc, ...innerArray.map(entry => entry.name)]
}, [])

console.log(names)

Upvotes: 0

devserkan
devserkan

Reputation: 17598

Because in your first map x is an array, not an object. So, there is no value. You should map inner arrays then get the desired value.

const arr = [
  [
    {
      name: "test",
      score: 40,
      date: "2018-09-18T00:00:00.000Z"
    },
    { name: "test2", score: 50, date: "2018-09-18T00:00:00.000Z" }
  ],
  [
    {
      name: "foo",
      score: 40,
      date: "2018-09-18T00:00:00.000Z"
    },
    { name: "bar", score: 50, date: "2018-09-18T00:00:00.000Z" }
  ]
];

const test1 = arr
  .map(x => x.map(y => y.name))
  .reduce((acc, el) => [...acc, ...el], []);


console.log(test1);

Upvotes: 1

Related Questions