Atlas91
Atlas91

Reputation: 5904

Get values passing a key value in javascript

I need create a kind of hashmap that i can't do to retrieve some values. This is the situation;

I've got a json with some properties like this one:

$scope.getItems = {
        "data": [{
            "label": "first-label",
                "objects": [{
                "name": "firstObj",
                    "attributes": [{
                    "attrname": "Item1",
                        "attrValue": "",
                        "attrType": "text"
                }, {
                    "attrname": "Item2",
                        "attrValue": "",
                        "attrType": "text"
                }]
            }],
               "properties": {
                "film:property": "action"
            }
        },
        {
            "label": "second-label",
                "objects": [{
                "name": "firstObj",
                    "attributes": [{
                    "attrname": "Item1",
                        "attrValue": "",
                        "attrType": "text"
                }, {
                    "attrname": "Item2",
                        "attrValue": "",
                        "attrType": "text"
                }]
            }],
               "properties": {
                "film:property": "action"
            }
        },
        {
            "label": "third-label",
                "objects": [{
                "name": "firstObj",
                    "attributes": [{
                    "attrname": "Item1",
                        "attrValue": "",
                        "attrType": "text"
                }, {
                    "attrname": "Item2",
                        "attrValue": "",
                        "attrType": "text"
                }]
            }],
               "properties": {
                "film:property": "drama"
            }
        },
        {
            "label": "fourth-label",
                "objects": [{
                "name": "firstObj",
                    "attributes": [{
                    "attrname": "Item1",
                        "attrValue": "",
                        "attrType": "text"
                }, {
                    "attrname": "Item2",
                        "attrValue": "",
                        "attrType": "text"
                }]
            }],
               "properties": {
                "film:property": "action"
            }
        },
        {
            "label": "fifth-label",
                "objects": [{
                "name": "firstObj",
                    "attributes": [{
                    "attrname": "Item1",
                        "attrValue": "",
                        "attrType": "text"
                }, {
                    "attrname": "Item2",
                        "attrValue": "",
                        "attrType": "text"
                }]
            }],
               "properties": {
                "film:property": "comic"
            }
        }

        ]
    };

Ok then, now, what i need is film:property and label. As you can see for the film:property "action" we have more that one label and exaclty:

- first-label
- second-label
- fourth-label

so an hypothetical tree view could be:

- action
   - first-label
   - second-label
   - fourth-label

 -drama
   - third-label

 -comic
   -fifth-label

I made a jsfiddle here: https://jsfiddle.net/vuqcopm7/58/ in which there is the same json and a list like this:

<ul data-ng-repeat="object in uniqueNames">
        <li ng-click="getLabelByProp(object)"> 
            <a style="cursor:pointer">{{object}}</a>
        </li>
      </ul> 

what i need is when i click over a item get the labels with that property.For example:

click over action and i need to display in somewhere, it's not important where,

 - first-label
    - second-label
    - fourth-label

and so on for the others. Thanks for help!

Upvotes: 0

Views: 799

Answers (2)

charlietfl
charlietfl

Reputation: 171690

I would map this data into a new structure with genre or category as top level and the individual films as children

[
  {genre: 'action', films:[]},
  {genre: 'drama', films:[]}
]

Following loops through all the films and uses the genre as key to group the films into respective sub arrays.

var tmp = {};

data.forEach(function(item) {
  var genre = item.properties["film:property"];
  if (!tmp[genre]) {
    tmp[genre] = []
  }
  tmp[genre].push(item)
});

Once all are in the temp object it is a simple map of those keys to create final scope model

$scope.filmCats = Object.keys(tmp).map(function(key) {
  return {
    genre: key,
    films: tmp[key]
  }
});

Basic HTML

  <div ng-repeat="item in filmCats">
    <h4>{{item.genre}}</h4>
    <ul>
      <li ng-repeat="film in item.films">{{film.label}}
        <ul>
          <li ng-repeat="obj in film.objects">{{obj.name}}</li>
        </ul>
      </li>
    </ul>
  </div>

Note: You could also do this with the filter groupBy that would only require adding a new property name to eaach film that is the value of "film:property"

DEMO

Upvotes: 1

koox00
koox00

Reputation: 2731

I used filter and map to get your result. So first filter for the matching property and then create an array only of labels and finally get unique values:

$scope.getLabelByProp = function(property) {
  var filtered = $scope.getItems.data
                .filter(byProperty(property))
                .map(getLabel)
                .filter(isUnique)
  console.log(filtered);
}

function isUnique(item, idx, items) {
  return items.indexOf(item) === idx;
}

function byProperty(property) {
  return function(item, i, items) {
    return item.properties["film:property"] == property
  }
}

function getLabel(n) {
  return n.label;
}

I'm not so sure about the uniqueness though.

fiddle

Upvotes: 1

Related Questions