2

I have two arrays

$scope.tags =  [{ "id": 1, "name": "python" }, { "id": 2, "name": "NodeJs" }, { "id": 3, "name": "git" }]

Other one is

$scope.skillsInterested = [1,2];

What is want to do ?

How can i map the above arrays and print only names of the id's in$scope.skillsInterested

I want to print names in first array only the id's present in second.

I have tried this after getting several answers

var tag_map = {};
for (var x = 0; x < $scope.tags.length; x++) {
tag_map[$scope.tags[x]['id']] = $scope.tags[x]['name'];
}
$scope.skillsInts = $scope.skillsInterested.map(function(x) {
return tag_map[x]

On running console.log

console.log("Result", tag_map);

It sometimes give result sometimes it gives 'map' of undefined.

TypeError: Cannot read property 'map' of undefined
at controllers.js:141
at angular.js:16383
at m.$eval (angular.js:17682)
at m.$digest (angular.js:17495)
at m.$apply (angular.js:17790)
at l (angular.js:11831)
at J (angular.js:12033)
at XMLHttpRequest.t.onload (angular.js:11966)

Thanks in advance.

3
  • Show us your forEach and what error you get Commented Nov 22, 2016 at 10:43
  • "Print only" means that you want to filter first array - developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… Commented Nov 22, 2016 at 10:45
  • $scope.tags.filter(x=>x.id === $scope.selectedExpTags )[0].name or $scope.tags.find(x=>x.id === $scope.selectedExpTags ).name Commented Nov 22, 2016 at 10:46

4 Answers 4

4

Make a map of your data that looks like this:

var tagMap = { 1: "python", 2: "NodeJs" /* etc. */ };

You can do this by looping over your tags and adding a new property to an object. reduce lets you do this without creating any extra variables.

Then, you can select names from your newly created object using the [] notation: tagMap[1] returns "pyhton".

var tags =  [{ "id": 1, "name": "python" }, { "id": 2, "name": "NodeJs" }, { "id": 3, "name": "git" }]
var selectedExpTags = [1,2];


// Make a map for `id: name`
var tagMap = tags.reduce(function(map, tag) {
  map[tag.id] = tag.name;
  return map;
}, {});

// Quickly select names from the map:
var selectedNames = selectedExpTags.map(function(id) {
  return tagMap[id];
});

console.log(selectedNames);

Using this approach, you minimise the iterations over your data. The creation of the map loops over the tags once. Creating the array with names, loops over the selected tags once. So, roughly, the "loop count" is tags.length + selectedTags.length. If you would use an indexOf based approach, your loop count would be tags.length * selectedTags.length.

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

4 Comments

Some times it gives the result, sometimes it throws map of undefined
selectedExpTags had to be an array
yes it is array please check the edits i have made, i have tried simple for loop and sometime it gives result and sometimes it throws error
Cannot read property 'map' of undefined means you have a variable that is undefined, and you're trying to access .map on it. For example: var a = undefined; a.map(); So I'd try something like: $scope.skillsInts = $scope.skillsInterested ? $scope.skillsInterested.map(/*etc*/) : [];. This sets skillsInts to an empty array when skillsInterested is not defined.
2

Use the filter function for first, and then check the id's existnent then map the names from the array.

var first = [{ "id": 1, "name": "python" }, { "id": 2, "name": "NodeJs" }, { "id": 3, "name": "git" }];

var selectedExpTags = [1,2];

var names = first.filter(item => selectedExpTags.some(id => item.id === id)).map(item => item.name);

console.log(names);

1 Comment

first.where is not a function"
2

You can loop over $scope.selectedExpTags and get a list of all names. You can use array.find if you want first value only.

Sample

var first = [
  { "id": 1, "name": "python" }, 
  { "id": 2, "name": "NodeJs" }, 
  { "id": 3, "name": "git" }];

var selectedExpTags = [1,2];
var names = selectedExpTags.map(x=> first.find( y=> y.id === x ).name )

console.log(names);

Comments

1
$scope.newArray = []; // If you need a new array to work with
angular.forEach($scope.tags, function(tag){
$scope.selectedExpTags.forEach(function(selectedTag){ 
    if(selectedTag == tag.id){
        //tag.hide = false; // - If you want to update the current array
        $scope.newArray.push(tag);
    }
    // else{ // - If you want to update the current array
    //      tag.hide = true;
    // }
  })
})

Lodash is more efficient than angular for manipulating data.

Comments

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.