【问题标题】:How to push properties to an array within an object within an array via looping?如何通过循环将属性推送到数组内对象内的数组?
【发布时间】:2019-06-20 03:05:19
【问题描述】:

我正在创建一个像调度程序一样运行的小型 Angular 应用程序。 它允许用户提供名称、开始和结束日期,并通过表单检查布尔复选框。

我的问题是我试图将每个用户条目的名称推送到数组中的特定日期,例如26/01/2019 将具有以下名称:“James”、“Mark”、“Luke”等,都在同一天,具体取决于用户通过表单输入。

在我的循环中,我为日期范围内的每个日期推送一个新对象,但无法找到将名称推送到每个日期对象内的字符串数组的方法。

我试图在另一个推送中将值推送到数组,这一直给我错误。

我注意到,如果我将循环中的 name 字段的值设置为“[value]”,由于某种原因它不会出错,但不知道为什么。

循环完成后,我想提醒生成的对象数组,但是当我编写代码执行此操作时,我收到“未定义”的提醒。值没有保存到数组中吗?

    import { Component, OnInit } from '@angular/core';
    import { NgForm } from '@angular/forms';
    import { IPreferences } from '../ipreferences';
    import { DatePipe } from '@angular/common';
    import * as moment from 'moment';

    @Component({
      selector: 'app-customer-form',
      templateUrl: './customer-form.component.html',
      styleUrls: ['./customer-form.component.css']
    })
    export class CustomerFormComponent implements OnInit {
      title = 'Preference Form';
      preferences: IPreferences;
      dateObj: { }; // to be array of Date objects containing Name sub-arrays
      nameArray: string[];
      date = new Date();
      constructor(public datepipe: DatePipe) {
        this.preferences = {
          name: '',
          dateFrom: null,
          dateTo: null,
          everyday: null
        }
      }

      getDates(startDate, endDate){
          var dates = [],
            currentDate = startDate,
            addDays = function(days) {
              var date = new Date(this.valueOf());
              date.setDate(date.getDate() + days);
              return date;
            };
        while (currentDate <= endDate) {
          dates.push(currentDate);
          currentDate = addDays.call(currentDate, 1);
        }
        return dates;
      }

        savePreferences(form): void {
        var savedName:string = this.preferences.name;
        var formatDateFrom:string = moment(this.preferences.dateFrom).format("YYYY-MM-DD");
        var formatDateTo:string = moment(this.preferences.dateTo).format("YYYY-MM-DD");
        var savedEveryday:Boolean = this.preferences.everyday;
        var savedDateFrom:Date = new Date(formatDateFrom);
        var savedDateTo:Date = new Date(formatDateTo);
        var dateRange = this.getDates(savedDateFrom, savedDateTo);

        if(!!savedEveryday){
          for(var i = Number(savedDateFrom); i <= Number(moment(savedDateFrom).format("YYYY-MM-DD") + 90); i++){ // 90 and not infinite as due to time constraints i intended to print
            // the first 90 dates regardless of scenario, so if a user selected to receive marketing info daily it would of "appeared" to be daily

            this.nameArray.push(savedName) // pushing name strings to nameArray
          }
        }

        if(!savedEveryday) {
          dateRange.forEach(date => {
            this.nameArray.push(savedName) // pushing name strings to nameArray
        })

        this.dateObj[Number(this.date)] = {
          name: this.nameArray // attempting to set name property of objects in array to nameArray strings (2d array)
          }
        }
        alert(this.nameArray.length); // attempting to test by having a pop up of the object array (Dates) with their corresponding names returned

      }

实际结果是“未定义”的警报。

我希望看到数组中的对象警报。每个对象都有不同的日期,并且每个对象中都有不同名称的数组。

【问题讨论】:

    标签: javascript arrays node.js angular typescript


    【解决方案1】:

    我理解你的问题的方式是:- 你想在同一个日期添加多个名称,同时你想添加新的日期。

    您实际上可以使用键值对概念来做到这一点。 键值对的基本结构是你需要创建一个空对象。 让一个 = {}; 并使用此对象输入值。 例如:在你提到的场景中:

    let dateObj = {};
    let name_array =[]; // this is a temporary storage for the name;
    let date =  new Date(); // this the date object that you are going to use as a key
    name_array.push("James");
    name_array.push("Mark");
    name_array.push("Luke");
    
    /*Below is the basic declaration of the key value pair in JavaScript*/
        dateObj[date] = {
        name: name_array
        }
    /*if you want to retrieve content that is associated with the key(DATE) object use*/
    dateObj[date].name // this will return all the name associated with that date object(key)
    

    如果要打印所有内容,请使用 for 循环遍历 DATE(键值对)。

    此方法的另一个优点是,如果您想输入名称 对于现有密钥,您不必遍历所有密钥 值对。

    您可以使用代码 日期对象[日期] = { 名称:name_array } 如果键存在,如果没有创建新的键值对,则可以执行更新。通过这种方式,您可以避免不必要的迭代至少据我所知,这是一种比其他方法更有效的方法

    【讨论】:

    • 我无法对 dateObj[date] = { name: name_array } 进行编码,因为我收到一条错误消息,告诉我 name_array 在彼此相邻声明时找不到
    【解决方案2】:

    我能够执行此代码。

     let dateObj = {};
    let name_array = []; // this is a temporary storage for the name;
    let date =  new Date(); // this the date object that you are going to use as a key
    name_array.push("James");
    name_array.push("Mark");
    name_array.push("Luke");
    print(name_array);
    /*Below is the basic declaration of the key value pair in JavaScript*/
        dateObj[date] = {
        name: name_array
        };
    
    /*if you want to retrieve content that is associated with the key(DATE) object use*/
    dateObj[date].name;
    print(dateObj[date].name);
    

    你能发布你的代码吗?我可以检查一下出了什么问题

    你可以把代码放在这里:https://rextester.com/l/js_online_compiler 并测试

    【讨论】:

    • 您好,我已根据您的建议实施更新了我的原始邮政编码。我现在遇到的问题是 savePreferences 函数在提醒 nameArray 的长度时失败,我认为这意味着值没有正确保存?
    • 如果有帮助,我认为我的问题出在“for”和 forEach 循环中,但我无法确定这是否是原因,或者是否是我尝试将 dateObj 的 name 属性设置为nameArray 或者 TypeScript 的语法是否不同
    • 首先你必须检查 savedEveryday 变量,看看它是 null、true 还是 false,你还必须检查 this.nameArray.push(savedName) 是否真的将名称推送到这个数组。你的 for 循环,我也怀疑,我认为你必须检查循环是否真的有效。如果上述几点有效,那么您的上述代码应该可以工作。需要注意的另一点是,moment.js 可以为您提供两个日期和一个数字之间的差异(如果有帮助的话),并且由于您将 90 天添加到 savedDateFrom 您可以使用 date.setDate(date.getDate( ) + 90);
    • 非常感谢您的帮助!原来我没有初始化 nameArray 或 DateObj。你说的 for 循环不能正常工作是对的,我现在已经修复了。两个循环现在都推送到 nameArray,但我在将 nameArray 作为 Name 属性推送到 dateObj 数组时遇到了一些麻烦……我想我只需要再研究一下键值对。
    • 键值对类似于您在 JAVA 中找到的 Maps 集合,但差异很小。无论如何我很高兴能为您提供一些帮助:)。
    猜你喜欢
    • 2021-06-14
    • 2022-12-17
    • 2014-11-12
    • 1970-01-01
    • 2019-11-02
    • 2017-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多