2

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?

0

3 Answers 3

6

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
Sign up to request clarification or add additional context in comments.

3 Comments

Its a great idea, but when I run it in apps script I get: [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null]
Does the # comes prefixed with whitespace in your real code? Could tou show how you implemented the suggestion?
You have to make sure the following is true: 1. map is called directly on the array of objects (objArray). 2. The " #" key consists exactly of whitespace and hash chars. 3. V8 runtime is enabled (the same goes for Mario's answer, btw)
3

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

4 Comments

Thank you - I'm fairly new to js and reduce. Would you mind explaining what you've done here?
I apologize , its a great explanation. I'm familiar and have used reduce before, but at a beginning level as in your explanation. I'm less clear about the function you are using - (previousValue, currentValue) => [...previousValue, currentValue[" #"]] - Is previous value the accumulator?
I understand. Yes previousValue is the accumulator. About [...previousValue, currentValue[" #"]] I am using spread syntax to expand the current accumulator in a new array plus the value of currentValue in property ` #`
@LDN - the [...sourceArray, value] is just a more concise way to right sourceArray.concat([ value ]) since ES6 came around (see spread in array literas)
2

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]

1 Comment

I find this a lot quicker to use to view results: SpreadsheetApp.getUi().showModalDialog(HtmlService.createHtmlOutput(oA.join('<br />')), "Display Results");

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.