【问题标题】:Array Mapping in AngularJsAngularJs 中的数组映射
【发布时间】:2016-11-22 10:42:00
【问题描述】:

我有两个数组

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

另一个是

$scope.skillsInterested = [1,2];

想做什么?

如何映射上述数组并仅打印 id 的名称$scope.skillsInterested

我想在 第一个数组中打印名称,只有第二个存在的 id。

我在得到几个答案后尝试过这个

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]

在运行 console.log

console.log("Result", tag_map);

有时会给出结果,有时会给出未定义的“地图”。

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)

提前致谢。

【问题讨论】:

标签: javascript angularjs arrays


【解决方案1】:

制作如下所示的数据地图:

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

您可以通过循环标记标签并向对象添加新属性来实现此目的。 reduce 让您无需创建任何额外变量即可完成此操作。

然后,您可以使用[] 表示法从新创建的对象中选择名称:tagMap[1] 返回"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);

使用这种方法,您可以最大限度地减少对数据的迭代。地图的创建循环标签 一次。创建带有名称的数组,循环选定的标签一次。所以,粗略地说,“循环计数”是tags.length + selectedTags.length。如果您使用基于indexOf 的方法,您的循环计数将是tags.length * selectedTags.length

【讨论】:

  • 有时会给出结果,有时会抛出未定义的映射
  • selectedExpTags 必须是一个数组
  • 是的,它是数组,请检查我所做的编辑,我尝试过简单的 for 循环,有时它会给出结果,有时它会抛出错误
  • Cannot read property 'map' of undefined 表示您有一个变量是undefined,并且您正尝试访问它上面的.map。例如:var a = undefined; a.map(); 所以我会尝试类似:$scope.skillsInts = $scope.skillsInterested ? $scope.skillsInterested.map(/*etc*/) : [];。当 skillsInterested 未定义时,这会将 skillsInts 设置为空数组。
【解决方案2】:

first 使用过滤功能,然后检查id 的存在性,然后检查map 数组中的名称。

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);

【讨论】:

  • first.where is not a function"
【解决方案3】:

您可以遍历$scope.selectedExpTags 并获取所有名称的列表。如果你只想要第一个值,你可以使用array.find

示例

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);

【讨论】:

    【解决方案4】:
    $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 在处理数据方面比 Angular 更有效。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-01-31
      • 2015-07-14
      • 1970-01-01
      • 1970-01-01
      • 2015-04-20
      • 1970-01-01
      • 2020-09-25
      相关资源
      最近更新 更多