打字稿:如何简单地将数组数组转换为<my model =“”>

时间:2018-05-10 02:18:33

标签: angular typescript multidimensional-array

我正在开发Angular 6.我想知道是否有一种简单的方法来处理一堆模型,这些模型描述了一堆相应数组中结构化值集的格式。我正在寻找一种简单的切割方法,而不是自定义创建代码,以使用For循环将每个数组的每个元素引入模型实例。有些模型更复杂,并且有几个级别的嵌套。

一个简单的案例:

型号:

export class User {
    firstName = '';
    lastName = '';
    userName = '';
    email = '';
}

阵列:

[
["Adam","Richardson","AdMan","Adam@example.com"],
["Ahmad","Ali","MarketMan","Ahmad@example.com"],
["Feng","Trunk","SuperMan","Feng@example.com"],
["Chris","Garcia","SmartMan","Donald@example.com"] 
]

有没有办法将模型神奇地叠加到仅值数组上?

3 个答案:

答案 0 :(得分:2)

如果您想要使用值数组中的数据填充任何对象的通用方法,您可以执行以下操作(只要您按照与数组中的数据相同的顺序声明类中的属性):

class User {
    firstName = '';
    lastName = '';
    userName = '';
    email = '';
}

const data = [
    ["Adam", "Richardson", "AdMan", "Adam@example.com"],
    ["Ahmad", "Ali", "MarketMan", "Ahmad@example.com"],
    ["Feng", "Trunk", "SuperMan", "Feng@example.com"],
    ["Chris", "Garcia", "SmartMan", "Donald@example.com"]
];

function fromDataArray<T>(klass: new () => T, data: any[]) {
    const obj = new klass();
    Object.keys(obj).forEach((k, i) => obj[k] = data[i]);

    return obj;
}

const users = data.map(d => fromDataArray(User, d));

制作适用于嵌套对象的泛型方法的一个问题是,一旦TypeScript被转换为JavaScript,所有类型都会丢失。消除该问题的唯一方法是在类中使用初始对象来实例化应该是具有该类型实例的对象的属性。

这是一个可以使用此类数据数组的嵌套对象的示例,以向您显示可以执行此操作:

function fromDataArray<T>(klass: new () => T, data: any[]) {
  const obj = new klass();
  Object.keys(obj).forEach((k, i) => {
    if (Array.isArray(obj[k])) {
      if (obj[k].length && typeof obj[k][0] === "object") {
        obj[k] = data[i].map(d => fromDataArray(obj[k][0].constructor, d));
      }
      else {
        obj[k] = data[i];
      }
    }
    else if (typeof obj[k] === "object") {
      obj[k] = fromDataArray(obj[k].constructor, data[i])
    }
    else {
      obj[k] = data[i];
    }
  });

  return obj;
}

class SubClass3 {
  email = '';
}

class SubClass2 {
  userName = '';
  stuffz = [new SubClass3()];
}

class SubClass1 {
  lastName = '';
  subClass2 = new SubClass2();
}

class Class1 {
  firstName = '';
  subClass1 = new SubClass1();
}

const data = [
  ["Adam", ["Richardson", ["AdMan", [ [ "Adam@example.com"] ]]]],
  ["Ahmad", ["Ali", ["MarketMan", [ [ "Ahmad@example.com"] ]]]],
  ["Feng", ["Trunk", ["SuperMan", [ [ "Feng@example.com"] ]]]],
  ["Chris", ["Garcia", ["SmartMan", [ [ "Donald@example.com"] ]]]]
];

const crazyData = data.map(d => fromDataArray(Class1, d));

这将给出一组如下所示的对象。

注意,这是JSON表示,但它们是相应类型的对象。

{
    "firstName": "Adam",
    "subClass1": {
        "lastName": "Richardson",
        "subClass2": {
            "userName": "AdMan",
            "stuffz": [
                {
                    "email": "Adam@example.com"
                }
            ]
        }
    }
}

答案 1 :(得分:0)

如何使用Array.prototype.map转换外部数组中的每个项目:

function userFromDataRow([firstName, lastName, userName, email]) => {
    const user = new User();

    user.firstName = firstName;
    user.lastName = lastName;
    user.userName = userName;
    user.email = email;

    return user;
});

// Assuming the array of arrays is called "data"
data.map(userFromDataRow);

答案 2 :(得分:0)

以下代码可能会为您提供所需的结果(有关演示,请参阅this stackblitz)。它将User对象的属性按其出现顺序映射到相应数组中的值。

export class User {
  firstName = '';
  lastName = '';
  userName = '';
  email = '';
}

export class AppComponent {

  users = new Array<User>();

  values = [
    ["Adam", "Richardson", "AdMan", "Adam@example.com"],
    ["Ahmad", "Ali", "MarketMan", "Ahmad@example.com"],
    ["Feng", "Trunk", "SuperMan", "Feng@example.com"],
    ["Chris", "Garcia", "SmartMan", "Donald@example.com"]
  ];

  createUsers() {
    this.values.forEach((value) => {
      let user = new User();
      Object.keys(user).map((key, index) => {
        user[key] = value[index];
      });
      this.users.push(user);
    });
  }
}