【问题标题】:How can I pull out two elements of every object in an array of objects and make a new one如何在对象数组中提取每个对象的两个元素并创建一个新元素
【发布时间】:2017-10-11 14:47:52
【问题描述】:

我有一个长度随时可能大于 1 的数组,并且会不断变大。

我只需要提取两个父数组元素的值并将它们放入一个新数组中。

这是基本数组的示例:

{
    "strains":[
            {
                "id": 150,
                "name": "Animal Cookies (Phat Panda)",
                "label": "Animal Cookies (Phat Panda)",
                "thcpct": 14,
                "cbdpct": 19,
                "ttlpct": 33,
                "type": "Hybrid SD",
                "subtype": "Sativa Dominant",
                "bitactive": 1,
                "useradded": "jjones",
                "dateadded": "4/12/2017"
            },
            {
                "id": 110,
                "name": "Blue Dream (Pioneer)",
                "label": "Blue Dream (Pioneer)",
                "thcpct": 24,
                "cbdpct": 0,
                "ttlpct": 24,
                "type": "Sativa",
                "subtype": "None",
                "bitactive": 1,
                "useradded": "jjones",
                "dateadded": "3/27/2017"
            },
            {
                "id": 30,
                "name": "Candyland",
                "label": "Candyland",
                "thcpct": 25,
                "cbdpct": 75,
                "ttlpct": 100,
                "type": "Hybrid SD",
                "subtype": "Sativa Dominant",
                "bitactive": 1,
                "useradded": "jjones",
                "dateadded": "1/1/2017"
            },
            {
                "id": 130,
                "name": "Dragon OG (Avitas)",
                "label": "Dragon OG (Avitas)",
                "thcpct": 26,
                "cbdpct": 18,
                "ttlpct": 44,
                "type": "Hybrid SD",
                "subtype": "Sativa Dominant",
                "bitactive": 1,
                "useradded": "jjones",
                "dateadded": "4/10/2017"
            }
    ]
}

这就是我希望它在提取后的样子:

{
    "strains":[
            {
                "id": 150,
                "label": "Animal Cookies (Phat Panda)",
            },
            {
                "id": 110,
                "label": "Blue Dream (Pioneer)",
            },
            {
                "id": 30,
                "label": "Candyland",
            },
            {
                "id": 130,
                "label": "Dragon OG (Avitas)",
            }
    ]
}

我尝试这样做的方法是使用 push,一个数组等于另一个数组,但我仍然得到 Push is NOT a function,或者“id”未定义并且代码停止。

这很简单,将一个数组元素分配给另一个数组元素并不难,但为什么这种情况如此不同?

我有我在这里尝试过的示例代码:

我在这里尝试过使用 LODASH:

//This is the call to the FIX_KEY function in appservice
  _.object(
     _.map(
      _.keys(allStrains.data),
         ctrlMain.appSvc.appFuncs.fix_key(/^name/, 'label')),
      _.values(allStrains.data)
  );

这是appservice中的函数:

svc.appFuncs = {
  //https://stackoverflow.com/questions/32452014/change-key-name-in-javascript-object
  //This replaces a STATIC key value for now, but can probably
  //replace any value
          fix_key: function (key, keyname) {
             return key.replace(key, keyname);
          }
}

我从 cmets 中的 Stack Overflow 问题修改了一个 lodash 代码。

更新 1:

Andrjez,请查看最终结果,了解我需要如何完成这项工作以及我遇到问题的位置:

             * Angular Dropdown Multi-select
             *
             * For STRAINS to select what will be in the room selected
             *
             */
            $scope.example8model = [];

            //Get the data from LOCALSTORAGE
            var getResults;
            **//I GET THE RESULTS from LOCAL STORAGE HERE**
            getResults = storageLocalService.getItemJSON("allstrains");
            **//CHECK the strains from LOCAL STORAGE**
            console.log("Strains: ", getResults.strains); //FAILS HERE!!!
            //getResults.strains is UNDEFINED but getResults HOLDS the JSON
            //EXACTLY how you made it in your example. I just changed
            //**obj** to **getResults**.



            var result = {
                //NEXT LINE FAILS: getResults.strains.map is UNDEFINED!    
                strains: getResults.strains.map(function (item) {
                    return {
                        id: item.id,
                        label: item.label
                    };
                })
            };

            console.log("All extracted Strains: ", result);

            $scope.example8model = result;

            //$scope.example8data = [
            //    {id: 1, label: "David"},
            //    {id: 2, label: "Jhon"},
            //    {id: 3, label: "Danny"}
            //];
            $scope.example8settings = {
                checkBoxes: true
            };

问题是:LOCAL STORAGE 中的数据没有前导或尾随双引号。但是...

这是我在 DEV CONSOLE 中得到的:

注意,没有为前导或尾随添加 DBL QUOTE:

然后当我点击到下一个级别时,添加了双引号,因此尝试访问:getResults.strains.map()...

最后,产生的错误...

那么,我哪里错了?

注意:这是我想要实现的目标:MULTI-SELECT

【问题讨论】:

    标签: javascript arrays


    【解决方案1】:

    使用Array.prototype.map:

    var result = { 
        strains: obj.strains.map(function (item) {
            return {
              id: item.id,
              label: item.label
            }; 
        })
    };
    

    试试下面的sn-p看看结果:

    var obj = {
        "strains":[
                {
                    "id": 150,
                    "name": "Animal Cookies (Phat Panda)",
                    "label": "Animal Cookies (Phat Panda)",
                    "thcpct": 14,
                    "cbdpct": 19,
                    "ttlpct": 33,
                    "type": "Hybrid SD",
                    "subtype": "Sativa Dominant",
                    "bitactive": 1,
                    "useradded": "jjones",
                    "dateadded": "4/12/2017"
                },
                {
                    "id": 110,
                    "name": "Blue Dream (Pioneer)",
                    "label": "Blue Dream (Pioneer)",
                    "thcpct": 24,
                    "cbdpct": 0,
                    "ttlpct": 24,
                    "type": "Sativa",
                    "subtype": "None",
                    "bitactive": 1,
                    "useradded": "jjones",
                    "dateadded": "3/27/2017"
                },
                {
                    "id": 30,
                    "name": "Candyland",
                    "label": "Candyland",
                    "thcpct": 25,
                    "cbdpct": 75,
                    "ttlpct": 100,
                    "type": "Hybrid SD",
                    "subtype": "Sativa Dominant",
                    "bitactive": 1,
                    "useradded": "jjones",
                    "dateadded": "1/1/2017"
                },
                {
                    "id": 130,
                    "name": "Dragon OG (Avitas)",
                    "label": "Dragon OG (Avitas)",
                    "thcpct": 26,
                    "cbdpct": 18,
                    "ttlpct": 44,
                    "type": "Hybrid SD",
                    "subtype": "Sativa Dominant",
                    "bitactive": 1,
                    "useradded": "jjones",
                    "dateadded": "4/10/2017"
                }
        ]
    };
    
    var result = { 
        strains: obj.strains.map(function (item) {
            return {
              id: item.id,
              label: item.label
            }; 
        })
    };
    
    console.log(result);

    如果你想使用 es6 功能:

    const result = { strains: obj.strains.map(({id , label}) => ({id, label})) };
    

    【讨论】:

    • 谢谢 Andrzej,这是“最佳”答案!
    • Andrzej,这不起作用,但这不是你的代码,这是我拉入 JSON 的方式...有关详细信息,请参阅更新 1!请查看....谢谢
    【解决方案2】:
    obj.strains = obj.strains.map(x => ({ id: x.id, label: x.label }));
    

    如果它不仅仅是应变,并且您想对每个子数组应用相同的逻辑:

    let filtered = Object.entries(obj)
      .filter(([k, arr]) => Array.isArray(arr))
      .reduce((acc, [k, arr]) => {
        acc[k] = arr.map(x => ({ id: x.id, label: x.label }));
        return acc;
      }, {});
    

    【讨论】:

    • obj.strains = obj.strains.map(x => ({ id: x.id, label: x.label }));
    • 是的,但是不兼容 ES6 的浏览器呢?使用通天塔?
    • @Shard map 不是边效,它会创建一个新数组。
    • @PeterTheAngularDude 你可以用function 替换箭头以获得大部分路径,map、filter 等是 ES 5 并且得到很好的支持。您还可能需要根据浏览器填充 Array.isArray 和 Object.entries,两者都很容易做到。
    • @Jared 你错过了一些括号,我编辑了我的评论
    【解决方案3】:

    我的解决方案:

    var test = 'label'
    var results = [];
    var response = strains.forEach( obj => {
        if (obj[test]) {
            results = [
                ...results,
                {
                    test: obj[test]
                }
            ];
        }
    });
    
    console.log('matches', results);
    //output: matches, [{test: "Animal Cookies (Phat Panda)"}, {test: "Blue Dream (Pioneer)"}, {test: "Candyland"}, {test: "Dragon OG (Avitas)"}]
    

    【讨论】:

      【解决方案4】:
      for (n of strains) {
          n = n.filter(function(elem,index){
              return (index == "id" || index == "label")
          });
      }
      

      类似的东西?

      【讨论】:

      • 像其他 cmets 建议的那样使用地图是更好的选择
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-31
      • 2022-11-22
      • 1970-01-01
      相关资源
      最近更新 更多