0

I am new in javascript and using nodejs and mongoose query to get a result which I would like to loop through and get some values in another array.

The resultset looks like

[ { _id: 5366e9049cfc825b32966852,
 companies:
     [ 5ab20bb69cb2754e949a09dc,
       5ac5d53983d45353bc6a9c54,
       5ac62eeca5421e4cb9abf63e]
},
{ _id: 5b9251f8ae8db624755f4b90,
 companies:
     [ 5b461c892bb9c81bd3ed4a25,
       5b5086196947782fbc873d28,
       5b76a6c79dc71a4a12564cc5 ]
}]

The final array should look like --

 [ 5ab20bb69cb2754e949a09dc,
   5ac5d53983d45353bc6a9c54,
   5ac62eeca5421e4cb9abf63e,
   5b461c892bb9c81bd3ed4a25,
   5b5086196947782fbc873d28,
   5b76a6c79dc71a4a12564cc5]

My code--

    Model.find().exec(function(err,gdoc){
          if(err)
          {
             callback({err:err,message:"Error looking up company"});
          }else
          {
             for (var i = 0, len = gdoc.length; i < len; i++) {                    
                    console.log(gdoc.companies);
              }
          }
    });

I am getting undefined values.

Any help is highly appreciated. Thanks in advance.

2
  • you are missing one closing curly bracket for for loop. not solution but just saying Commented Sep 12, 2018 at 13:46
  • @NimitkumarShah Updated. Commented Sep 12, 2018 at 13:49

7 Answers 7

2

The reason why you are getting undefined is that you try to access the non-existing companies property on gdoc. Instead of gdoc.companies, you have to use gdoc[i].companies.

Instead of your loop, you can use Array.prototype.concat together with the spread syntax (...) and Array.prototype.map as follows:

const gdoc = [
  {
    _id: '5366e9049cfc825b32966852',
    companies: [
      '5ab20bb69cb2754e949a09dc',
      '5ac5d53983d45353bc6a9c54',
      '5ac62eeca5421e4cb9abf63e',
    ],
  },
  {
    _id: '5b9251f8ae8db624755f4b90',
    companies: [
      '5b461c892bb9c81bd3ed4a25',
      '5b5086196947782fbc873d28',
      '5b76a6c79dc71a4a12564cc5',
    ],
  },
];

const companies = [].concat(...gdoc.map(doc => doc.companies));
console.log(companies);

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

1 Comment

Brilliant. The only thing which I was getting is a red mark under three dots. Then I change the ES version in my editor and all good. Thanks a lot.
0

Basically you're trying to concatenate all the company fields of the results array. As long as you know that the key is companies, this is an easy reduction.

Arrays have a couple of builtin methods that make transforming them very easy, compared to having to use a for-loop.

Array.forEach(), Array.map(), Array.reduce() and Array.find() are the most frequently used ones.

//  Since these id's contain letters as well, they need to be strings.
const data = [
  {
    _id: "5366e9049cfc825b32966852",
    companies:[
      "5ab20bb69cb2754e949a09dc",
      "5ac5d53983d45353bc6a9c54",
      "5ac62eeca5421e4cb9abf63e"
    ]
  },
  {
    _id: "5b9251f8ae8db624755f4b90",
   companies:[
    "5b461c892bb9c81bd3ed4a25",
    "5b5086196947782fbc873d28",
    "5b76a6c79dc71a4a12564cc5"
    ]
  }
];

const companies = data.reduce(( result, item ) => result.concat( item.companies ), []);

console.log( companies );

Comments

0

You can use the following method:

const map = [...[].concat(...arr.map((o) => o.companies))]

var arr = [ { _id: "5366e9049cfc825b32966852",
 companies:
     [ "5ab20bb69cb2754e949a09dc",
       "5ac5d53983d45353bc6a9c54",
       "5ac62eeca5421e4cb9abf63e"]
},
{ _id: "5b9251f8ae8db624755f4b90",
 companies:
     [ "5b461c892bb9c81bd3ed4a25",
       "5b5086196947782fbc873d28",
       "5b76a6c79dc71a4a12564cc5" ]
}];


const map = [...[].concat(...arr.map((o) => o.companies))]

console.log(map);

Comments

0

How about running a reduce over the array.

const model = [{
    _id: "5366e9049cfc825b32966852",
    companies: [
      "5ab20bb69cb2754e949a09dc",
      "5ac5d53983d45353bc6a9c54",
      "5ac62eeca5421e4cb9abf63e"
    ]
  },
  {
    _id: "5b9251f8ae8db624755f4b90",
    companies: [
      "5b461c892bb9c81bd3ed4a25",
      "5b5086196947782fbc873d28",
      "5b76a6c79dc71a4a12564cc5"
    ]
  }
];

const reducer = (acc, value) => {
  acc.push(...value.companies);
  return acc;
};

console.log(model.reduce(reducer, []));

Comments

0

You can do some thing like that!

var docs= [ { _id: "5366e9049cfc825b32966852",
 companies:
     [ "5ab20bb69cb2754e949a09dc",
       "5ac5d53983d45353bc6a9c54",
       "5ac62eeca5421e4cb9abf63e"]
},
{ _id: "5b9251f8ae8db624755f4b90",
 companies:
     [ "5b461c892bb9c81bd3ed4a25",
       "5b5086196947782fbc873d28",
       "5b76a6c79dc71a4a12564cc5" ]
}];
// your companies will be put in the folowing variable
var companies = [];

for ( var doc of docs){
    for (var item of doc.companies){
        companies.push(item)
    }
}

console.log(companies)

Comments

0

const data = [ { _id: '5366e9049cfc825b32966852',
 companies:
     [ '5ab20bb69cb2754e949a09dc',
       '5ac5d53983d45353bc6a9c54',
       '5ac62eeca5421e4cb9abf63e']
},
{ _id: '5b9251f8ae8db624755f4b90',
 companies:
     [ '5b461c892bb9c81bd3ed4a25',
       '5b5086196947782fbc873d28',
       '5b76a6c79dc71a4a12564cc5' ]
}]
let outputArr = []
data.map(d => outputArr.push(d.companies));
//Flatten
console.log([].concat.apply([],outputArr))

Both flatMap and flat which are currently an 'experimental technology' will allow a cleaner approach to this problem in the future. See:

Array.prototype.flat(): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat

Array.prototype.flatMap(): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flatMap

Comments

-1

You want something like this:

var k = [{
    _id: "5366e9049cfc825b32966852",
    companies: ["5ab20bb69cb2754e949a09dc",
      "5ac5d53983d45353bc6a9c54",
      "5ac62eeca5421e4cb9abf63e"
    ]
  },
  {
    _id: "5b9251f8ae8db624755f4b90",
    companies: ["5b461c892bb9c81bd3ed4a25",
      "5b5086196947782fbc873d28",
      "5b76a6c79dc71a4a12564cc5"
    ]
  }
];

var res = [];
k.forEach(function(id) {
  res.push(...id.companies)
});


console.log(res);

2 Comments

This returns an array of arrays, OP wants an array of strings
This does not return an array of arrays since the three dots will spread the companies array into multiple values and array.push() accepts multiple arguments. My question would be, why use forEach() to mimic reduce() ?

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.