user1592380
user1592380

Reputation: 36317

Apps script: map not returning expected value to array

I have an array of objects that looks like:

var objArray = [
  {
    " #": "4596",
    " E": "Yes",
    " Date": "06/12/20",
    " County": "Los Angeles County",
    " State": "California",
    " Acres": "2.49",
    " Eager": "Low",
  },
  {
    " #": "4588",
    " E": "Yes",
    " Date": "06/11/20",
    " County": "Towns County",
    " State": "Georgia",
    " Acres": "3.00",
    " Eager": "High",
  },
  ....
];

I'm trying to put together an array of the indexes ('#');

So far I have:

let indexes = objArray.forEach(function (rowObj) {
  Object.keys(rowObj).map(function (key) {
    if (key.includes("#")) {
      var v = rowObj[key];
      Logger.log(v); // abc
      return v;
    }
  });
});

Logger.log(indexes); // abc

output:

[20-06-13 20:43:33:320 EDT] 4547
[20-06-13 20:43:33:324 EDT] 4546
[20-06-13 20:43:33:329 EDT] 4545
[20-06-13 20:43:33:450 EDT] 4543
[20-06-13 20:43:33:453 EDT] 4542
[20-06-13 20:43:33:456 EDT] 4540
[20-06-13 20:43:33:459 EDT] 4538

This is producing:

[20-06-13 20:43:33:462 EDT] null

What am I doing wrong?

Upvotes: 2

Views: 125

Answers (3)

Mario
Mario

Reputation: 4998

If the key you are looking for is always # and if it is present in all objects you could simplify the logic using reduce. Please look at the following example

const objArray = [
  {
    " #": "4596",
    " E": "Yes",
    " Date": "06/12/20",
    " County": "Los Angeles County",
    " State": "California",
    " Acres": "2.49",
    " Eager": "Low",
  },
  {
    " #": "4588",
    " E": "Yes",
    " Date": "06/11/20",
    " County": "Towns County",
    " State": "Georgia",
    " Acres": "3.00",
    " Eager": "High",
  },
];

const output = objArray.reduce(
  (previousValue, currentValue) => [...previousValue, currentValue[" #"]],
  []
);

console.log(output)

Update 0

Reduce you use it when you need to compact the content of an array, its operation is very similar to filter and map in that they use a callback function that is executed in each entry of the array, the difference is that it reduces takes as initialValue argument which you update in each iteration.

For example, this is the same version without the shortcuts that allow you to use the arrow functions, previousValue corresponds to the initialValue, and currentValue to the object in each iteration. So in each iteration you spread the content of previousValue and get and attach the value of the # property of currentValue

Run the example so you can see the values of the previousValue in each iteration

const objArray = [
  {
    " #": "4596",
    " E": "Yes",
    " Date": "06/12/20",
    " County": "Los Angeles County",
    " State": "California",
    " Acres": "2.49",
    " Eager": "Low",
  },
  {
    " #": "4588",
    " E": "Yes",
    " Date": "06/11/20",
    " County": "Towns County",
    " State": "Georgia",
    " Acres": "3.00",
    " Eager": "High",
  },
];

const output = objArray.reduce((previousValue, currentValue) => {
  console.log(previousValue);
  previousValue = [...previousValue, currentValue[" #"]];

  return previousValue;
}, []);

console.log(output);

This post was the first I read about reduce, it explains the concept in a practical and simple way. I recommend your reading. Cheers

Upvotes: 3

0Valt
0Valt

Reputation: 10355

As a supplementary answer:

You can do this even simpler and faster.

const values = [
  { " #": "4596", " E": "Yes"},
  { " #": "4597", " E": "No"},
  { " #": "4598", " E": "Maybe"},
]

const indices = values.map(({ " #" : id }) => id);

console.log(indices);

Please, note that callback to map() method should be deterministic to acheive a consistent result.

Actual problem

Check the documentation on forEach() method - it is intended for producing side-effects and therefore returns void (literally no value), hence the last Logger.log(indexes); issue.

Useful links

  1. map() method reference
  2. Arrow functions guide
  3. forEach() method reference

Upvotes: 6

Cooper
Cooper

Reputation: 64100

I think your return in the middle of the loop was the problem. Other than that it's okay works fine.

This works for me:

function functest() {
  var objArray =[{" #":"4596"," E":"Yes"," Date":"06/12/20"," County":"Los Angeles County"," State":"California"," Acres":"2.49"," Eager":"Low"},
                 {" #":"4588"," E":"Yes"," Date":"06/11/20"," County":"Towns County"," State":"Georgia"," Acres":"3.00"," Eager":"High"},
                 {" #":"4596"," E":"Yes"," Date":"06/12/20"," County":"Los Angeles County"," State":"California"," Acres":"2.49"," Eager":"Low"},
                 {" #":"4588"," E":"Yes"," Date":"06/11/20"," County":"Towns County"," State":"Georgia"," Acres":"3.00"," Eager":"High"},
                 {" #":"4596"," E":"Yes"," Date":"06/12/20"," County":"Los Angeles County"," State":"California"," Acres":"2.49"," Eager":"Low"},
                 {" #":"4588"," E":"Yes"," Date":"06/11/20"," County":"Towns County"," State":"Georgia"," Acres":"3.00"," Eager":"High"},
                 {" #":"4596"," E":"Yes"," Date":"06/12/20"," County":"Los Angeles County"," State":"California"," Acres":"2.49"," Eager":"Low"},
                 {" #":"4588"," E":"Yes"," Date":"06/11/20"," County":"Towns County"," State":"Georgia"," Acres":"3.00"," Eager":"High"}];
  var oA=[];
  let indexes=objArray.forEach(function(rowObj) {
    Object.keys(rowObj).map(function(key) {
      if (key.includes('#') ) {
        var v = rowObj[key];
        oA.push(v);
      }
    });
  });
  Logger.log(oA);
}//[4596, 4588, 4596, 4588, 4596, 4588, 4596, 4588]

Upvotes: 2

Related Questions