【问题标题】:angularjs split json array into different arraysangularjs将json数组拆分为不同的数组
【发布时间】:2016-11-17 15:47:51
【问题描述】:

在我的应用程序中使用 http.post 从多个数组获取已在服务器上形成的 json 数组。 现在我的问题是我应该将此数组拆分为四个单独的数组,我将解释: JSON 数组示例

[{"Day", "11/17/2016", "time": "09:45"},
{ "Day", "17/11/2016", "time": "16:50"}, (.....)
{ "Day", "18/11/2016", "time": "11:25"},
{ "Day", "18/11/2016", "time": "12:30"}, (.....)
{ "Day", "11/21/2016", "time": "16:10"},
{ "Day", "11/21/2016", "time": "17:25"}]

现在我应该从这个数组中创建 4 个数组,第一个数组将存储几天,例如 (17.11.2016, 11.18.2016, 21.11.2016),第二个数组将存储所有时间”属于“第一天例如(09:45, 16:50),第三天将全部存储”属于“第二天,例如(11:25, 12:30)和第四天其中将存储“属于”第三天的所有时间,例如 (16:10, 17:25)。

所以结果会是这样的:

结果

First array: (17.11.2016, 11.18.2016, 21.11.2016)
Second array: (09:45, 16:50)
Third array: (11:25, 12:30)
Fourth array: (16:10, 17:25)

谁能帮帮我或给点建议?

谢谢

更新: 这是我的控制器,我在其中检索 JSON 数组:

.controller('AppCtrl', function($scope, $http) {
    $scope.data = {};

    $scope.submit = function(){
        var link = 'http://localhost/ShuttleFIX/api.php';
        $scope.var = "prova";
        $http.post(link, {username : $scope.data.username}).then(function (res){
            $scope.response = res.data;
        });
    };
});

我应该选择以下选项:17.11.2016、11.18.2016、21.11.2016

然后选择我应该有这些选项的地方:09:45,如果我选择第一天,则为 16:50

【问题讨论】:

  • 你给了我们一个很好的例子,但你没有给我们如何创建 4 个数组的逻辑。
  • 我需要 4 个数组,因为我应该有一个带有两个选择的表单,一个用于选择一天,第二个用于选择当天的时间
  • 在我看来,您正在尝试一种过于困难的解决方案来解决一个相当简单的问题。不过还是有点模糊,你能用一些代码更新这个问题吗?
  • 好的,我现在更新它

标签: javascript angularjs arrays json


【解决方案1】:

问题如何在我的控制器中为我的数组 ($scope.response) 插入此函数?

要转换传入的响应,您应该将传递给 $http 请求的 配置对象transformResponse 属性设置为 函数,它将根据您的需要转换传入的数据。请参阅transforming-requests-and-responses 了解更多信息。

我强烈建议您将用于从服务器获取数据的代码移动到 服务,而不是将其写入 控制器 本身,该服务将充当媒介向服务器发送 GET、POST 等请求,控制器的工作是进行数据绑定、用户交互和前端逻辑。请参阅this 了解更多信息以及以下代码 sn-p 中使用的编码风格。

here 是下面代码 sn-p 的 Plunker 链接。

Angular 代码。

angular
  .module('demo', [])
  .controller('DefaultController', DefaultController)
  .factory('dataService', dataService);

DefaultController.$inject = ['dataService'];

function DefaultController(dataService) {
  var vm = this;

  getEvents();

  function getEvents() {
    return dataService.getEvents()
      .then(function (data) {
        vm.data = data;
        return vm.data;
      });
  }
}

dataService.$inject = ['$http'];

function dataService($http) {
  var service = {
    getEvents: getEvents
  };

  return service;

  function getEvents() {
    var config = {
      transformResponse: function (data, headers) {
        if(headers("content-type") === "application/json; charset=utf-8" && angular.isString(data)) {
          var result = {
            events: [],
            schedules: []
          };

          var events = JSON.parse(data);
          var dates = [];
          for (var i = 0; i < events.length; i++) {
            if (dates.indexOf(events[i].day) === -1) {
              var date = events[i].day;
              dates.push(date);
              result.events.push({
                date: date
              });
            }

            result.schedules.push({
              date: events[i].day,
              time: events[i].time
            });
          }

          return result;
        } else {
          return data;
        }
      }
    };

    return $http.get('events.json', config)
      .then(getEventsCompleted)
      .catch(getEventsFailed);

    function getEventsCompleted(response) {
      return response.data;
    }

    function getEventsFailed(error) {
      console.error(error);
    }
  }
}

events.json

[{
    "day": "11/17/2016",
    "time": "09:45"
  }, {
    "day": "17/11/2016",
    "time": "16:50"
  }, {
    "day": "18/11/2016",
    "time": "11:25"
  }, {
    "day": "18/11/2016",
    "time": "12:30"
  }, {
    "day": "11/21/2016",
    "time": "16:10"
  }, {
    "day": "11/21/2016",
    "time": "17:25"
  }]

视图。

<div ng-app="demo">
  <div ng-controller="DefaultController as ctrl">
    <div class="form-group">
      <label>Event Date</label>
      <select ng-options="event as event.date for event in ctrl.data.events" ng-model="ctrl.event">
        <option value="">Select</option>
      </select>
    </div>
    <div class="form-group">
      <label>Event Time</label>
      <select ng-options="schedule as schedule.time for schedule in ctrl.data.schedules | filter: { date: ctrl.event.date}" ng-model="ctrl.schedule" ng-disabled="!ctrl.event">
        <option value="">Select</option>
      </select>
    </div>
  </div>
</div>

注意:如果您不想创建数据服务,则可以将根据需要转换源数据的函数放在控制器中,并在 $http 请求的成功回调中调用它。

$scope.submit = function() {
    ...
    $http.post(link, { username : $scope.data.username }).then(function (response) {
        $scope.response = processItems(response.data);
    });

    function processItems(events) {
        ...
    }
};

【讨论】:

  • 这很完美,我会试试,希望能解决我的问题,非常感谢!!
  • 控制台返回一个错误:加载资源失败:服务器响应状态为 404(未找到)app.js:106 Objectconfig: Objectdata: "Cannot GET /events. json↵"headers: (name)status: 404statusText: "Not Found"_proto_: ObjectgetEventsFailed @ app.js:106
  • 如果您尝试从“events.json”获取模拟数据,请使用您的问题中的 api 调用替换“events.json”,即此网址“localhost/ShuttleFIX/api.php”根据您在 $http 请求中指定的路径检查文件是否存在并且它是否在正确的文件夹中,例如上面给出的脚本和 events.json 都在同一个文件夹中。尝试在回调中添加断点,看看问题出在哪里。
  • 我试图从“events.json”中检索数据并形成服务器(localhost/ShuttleFIX/api.php),但在这两种情况下我都没有检索到任何内容
  • @Edoardo,在 transformResponse 函数的最开始保留一个调试器并检查您是否正在获取数据
【解决方案2】:

我建议你使用 MomentJS 库来处理日期。

然后,在你的数组上循环,读取Day 属性,进行计算(使用 MomentJS,你有一些很好且易于使用的函数来知道它是今天还是过去等)并将其添加到正确的数组。

在本例中,您从服务器接收到的数组存储在变量data 中。

var firstArray = [], 
  secondArray = [], 
  thirdArray = [], 
  fourthArray = [];

data.forEach(function(entry) {
  var day = moment(entry.Day, "MM/DD/YYYY");
  /* your computation here to know in which array it'll go */
})

【讨论】:

    【解决方案3】:

    首先,数组格式不正确:)我做了一些小改动:

    var arr = [
        { "Day": "11/17/2016", "time": "09:45"},
        { "Day": "17/11/2016", "time": "16:50"}, 
        { "Day": "18/11/2016", "time": "11:25"},
        { "Day": "18/11/2016", "time": "12:30"}, 
        { "Day": "11/21/2016", "time": "16:10"},
        { "Day": "11/21/2016", "time": "17:25"}
    ]
    

    我声明后,2个数组:

    var First = [];
    var Second = [];
    

    最后我在新数组中推送了我想要的内容:

    arr.forEach(function(item){
        First.push(item.Day);
        Second.push(item.time);
    })
    

    【讨论】:

      【解决方案4】:

      使用Array.prototype.reduce 创建一个对象,其中day 作为keytimes 作为值数组,并从中获取所需的数组 - 参见下面的演示:

      var array=[{"Day":"11/17/2016","time":"09:45"},{"Day":"17/11/2016","time":"16:50"},{"Day":"18/11/2016","time":"11:25"},{"Day":"18/11/2016","time":"12:30"},{"Day":"11/21/2016","time":"16:10"},{"Day":"11/21/2016","time":"17:25"}];
      
      var result = array.reduce(function(prev,curr){
        prev[curr.Day] = prev[curr.Day] || [];
        prev[curr.Day].push(curr.time);
        return prev;
      },{});
      
      // list of days
      console.log("Days: ", Object.keys(result));
      
      // get times for each day by using date as a key
      for(var key in result) {
        console.log(key + " => " + result[key]);
      }
      .as-console-wrapper{top:0;max-height:100%!important;}

      【讨论】:

        【解决方案5】:

        这是我的建议,虽然只用 JS 也可以,但使用 Lodash 来简化。

        另外,请注意日期格式不一致,因此我尝试使用 DD/MM/YYYY 格式来理解它。

        var arr = [
                { "Day": "17/11/2016", "time": "09:45"},
                { "Day": "17/11/2016", "time": "16:50"}, 
                { "Day": "18/11/2016", "time": "11:25"},
                { "Day": "18/11/2016", "time": "12:30"}, 
                { "Day": "21/11/2016", "time": "16:10"},
                { "Day": "21/11/2016", "time": "17:25"}
            ];
            
        // Group the times by the date
        var grouped = _(arr)
        .groupBy('Day')
        .mapValues(v => _.map(v, 'time'))
        .mapKeys((v, k) => moment(k, 'DD/MM/YYYY').format('DD.MM.YYYY'))
        .value();
        
        // Massage the grouped times
        var result = [_.keys(grouped)];
        result.push.apply(result, _.values(grouped));
        
        console.log(result);
        <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.16.0/moment.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.2/lodash.min.js"></script>

        【讨论】:

        • 感谢您的回复,它有效,我只有一个问题,如果您看到我的更新,我会从服务器检索包含日期和时间的数组,所以您能帮我解决这个问题吗?有一个有两个选择的表格,第一个有天,第二个随着包含时间的日期的选择而动态变化。谢谢
        【解决方案6】:

        您可以创建两个数组,一个用于日期列表,另一个用于时间列表,作为您从服务器获取的源数组中的两个 &lt;select&gt; 元素的数据源,您需要一个属性将有助于识别 b/w 日期和时间数组的关系,即此处的日期属性。

        请检查下面的代码sn-p,时间下拉列表使用日期属性过滤为filter: { date: ctrl.event.date},希望对您有所帮助。

        angular
          .module('demo', [])
          .controller('DefaultController', DefaultController);
        
        function DefaultController() {
          var vm = this;
          var events = [{
            "day": "11/17/2016",
            "time": "09:45"
          }, {
            "day": "17/11/2016",
            "time": "16:50"
          }, {
            "day": "18/11/2016",
            "time": "11:25"
          }, {
            "day": "18/11/2016",
            "time": "12:30"
          }, {
            "day": "11/21/2016",
            "time": "16:10"
          }, {
            "day": "11/21/2016",
            "time": "17:25"
          }];
        
          vm.data = processItems(events);
        
          function processItems(events) {
            var result = {
              events: [],
              schedules: []
            };
        
            var dates = [];
            for (var i = 0; i < events.length; i++) {
              if (dates.indexOf(events[i].day) === -1) {
                var date = events[i].day;
                dates.push(date);
                result.events.push({
                  date: date
                });
              }
        
              result.schedules.push({
                date: events[i].day,
                time: events[i].time
              });
            }
        
            return result;
          }
        }
        .form-group {
          margin: 10px;
        }
        .form-group * {
          width: 100px;
        }
        .form-group label {
          float: left;
        }
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
        <div ng-app="demo">
          <div ng-controller="DefaultController as ctrl">
            <div class="form-group">
              <label>Event Date</label>
              <select ng-options="event as event.date for event in ctrl.data.events" ng-model="ctrl.event">
                <option value="">Select</option>
              </select>
            </div>
            <div class="form-group">
              <label>Event Time</label>
              <select ng-options="schedule as schedule.time for schedule in ctrl.data.schedules | filter: { date: ctrl.event.date}" ng-model="ctrl.schedule" ng-disabled="!ctrl.event">
                <option value="">Select</option>
              </select>
            </div>
          </div>
        </div>

        如果您可以控制服务器代码,我建议您获取如下所示的响应 JSON。

        var data = {
          events: [
            { eventId: 1, eventDate: '11/17/2016' },
            { eventId: 2, eventDate: '12/18/2016' },
            { eventId: 3, eventDate: '12/21/2016' }
          ],
          timings: [{
            { eventId: 1, eventTime: '10:00' },
            { eventId: 1, eventTime: '12:30' },
            { eventId: 2, eventTime: '16:50' },
            { eventId: 3, eventTime: '17:50' }
          }]
        };
        

        尽管您可以将获得的源数组用于两个下拉列表,如下所示,例如不过我不推荐它,因为随着时间的推移,当事情开始变得复杂或系统发生变化时,维护起来会变得很困难。

        angular
          .module('demo', [])
          .controller('DefaultController', DefaultController)
          .filter('unique', unique);
        
        function DefaultController() {
          var vm = this;
          vm.events = [{
            "day": "11/17/2016",
            "time": "09:45"
          }, {
            "day": "17/11/2016",
            "time": "16:50"
          }, {
            "day": "18/11/2016",
            "time": "11:25"
          }, {
            "day": "18/11/2016",
            "time": "12:30"
          }, {
            "day": "11/21/2016",
            "time": "16:10"
          }, {
            "day": "11/21/2016",
            "time": "17:25"
          }];
        }
        
        function unique() {
          return function(input, key) {
            var unique = {};
            var uniqueList = [];
            for (var i = 0; i < input.length; i++) {
              if (typeof unique[input[i][key]] == "undefined") {
                unique[input[i][key]] = "";
                uniqueList.push(input[i]);
              }
            }
            return uniqueList;
          };
        }
        .form-group {
          margin: 10px;
        }
        .form-group * {
          width: 100px;
        }
        .form-group label {
          float: left;
        }
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
        <div ng-app="demo">
          <div ng-controller="DefaultController as ctrl">
            <div class="form-group">
              <label>Event Date</label>
              <select ng-options="event as event.day for event in ctrl.events | unique: 'day'" ng-model="ctrl.event">
                <option value="">Select</option>
              </select>
            </div>
            <div class="form-group">
              <label>Event Time</label>
              <select ng-options="schedule as schedule.time for schedule in ctrl.events | filter: { day: ctrl.event.day}" ng-model="ctrl.schedule" ng-disabled="!ctrl.event">
                <option value="">Select</option>
              </select>
            </div>
          </div>
        </div>

        【讨论】:

        • 谢谢,我怎样才能在我的控制器中为我的数组 ($scope.response) 插入这个函数?
        • @Edoardo,您可以使用转换,查看我的答案,了解转换传入数据的代码的位置
        猜你喜欢
        • 1970-01-01
        • 2018-01-09
        • 1970-01-01
        • 1970-01-01
        • 2014-07-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-12-07
        相关资源
        最近更新 更多