用immutable.js合并两段不匹配的数据?

时间:2017-01-18 19:07:00

标签: javascript node.js ecmascript-6 immutability immutable.js

我有一段JSON数据用于动态生成表单,它看起来像这样:

{
  "form": {
    "fields": [
      {
        "name": "First Name",
        "alt": "first_name"
      },
      {
        "name": "Last Name",
        "alt": "last_name"
      },
      {
        "name": "D.O.B.",
        "alt": "dob"
      },
      {
        "name": "Primary Address",
        "alt": "primary_address"
      },
      {
        "name": "Primary City",
        "alt": "primary_city"
      },
      {
        "name": "ZIP Code",
        "alt": "zip"
      },
      {
        "name": "Country",
        "alt": "country"
      },
      {
        "name": "First 4 Phone Digits",
        "alt": "first_phone"
      },
      {
        "name": "Phone Number",
        "alt": "phone_number"
      }
    ]
  },
  "someVal": [],
  "someVal2": "a string"
}

当我提交此表单并且有错误时,我会以下列格式返回错误:

    [
      { 
        "alt": "primary_city",
        "errors": [ "primary_city Error Message" ] 
      },
      { 
        "alt": "zip",
        "errors": [ "zip Error Message" ] 
      },
      { 
        "alt": "first_name",
        "errors": [ "first_name Error Message" ] 
      },
      { 
        "alt": "dob",
        "errors": [ "dob Error Message" ] 
      },
      { 
        "alt": "primary_address",
        "errors": [ "primary_address Error Message" ] 
      },
      { 
        "alt": "last_name",
        "errors": [ "last_name Error Message" ] 
      }
    ]

我的目标是合并两者以获得此格式,以合并alts匹配的错误:

    {
      "form": {
        "fields": [
          {
            "name": "First Name",
            "alt": "first_name",
            "errors": [ "first_name Error Message" ]
          },
          {
            "name": "Last Name",
            "alt": "last_name",
            "errors": [ "last_name Error Message" ]
          },
          {
            "name": "D.O.B.",
            "alt": "dob",
            "errors": [ "dob Error Message" ]
          },
          {
            "name": "Primary Address",
            "alt": "primary_address",
            "errors": [ "primary_address Error Message" ]
          },
          {
            "name": "Primary City",
            "alt": "primary_city",
            "errors": [ "primary_city Error Message" ]
          },
          {
            "name": "ZIP Code",
            "alt": "zip",
            "errors": [ "zip Error Message" ]
          },
          {
            "name": "Country",
            "alt": "country"
          },
          {
            "name": "First 4 Phone Digits",
            "alt": "first_phone"
          },
          {
            "name": "Phone Number",
            "alt": "phone_number"
          }
        ]
      },
      "someVal": [],
      "someVal2": "a string"
    }

到目前为止,我一直在尝试执行以下操作:

import { fromJS, Map, List } from 'immutable';

import form from './json/form.json'
import config from './json/errors.json'

let list = new List([])

list.merge(fromJS(config), fromJS(form));

console.log(list);

console.log(list.toJS())
// console.log(JSON.stringify(newList, null, 2))

我只得到以下输出:

List []
[]

老实说,我不知道如何开始合并这些文档并且文档也没有多大帮助。

1 个答案:

答案 0 :(得分:1)

首先,你需要了解那里的不变性概念

let list = new List([])

const mergedList = list.merge(fromJS(config), fromJS(form));

console.log(list); // prints empty list

不变性意味着原始数据不会更新(例如变异)。在您的示例中,这意味着原始list对象仍将为空。但是.merge()会返回一个包含合并操作结果的新List。

然后你会看到Immutable中的列表被索引合并。看看这个简单的例子

const a = new List([{a: 1}, {a: 2}]);
const b = new List([{b: 3}, {b: 4}]);

const merged = a.merge(b);

console.log(merged.toJS())
// [{a: 1, b: 3}, {a: 2, b: 4}]

如果您希望不是按索引合并,而是按照您的特定标识符进行合并,则应将记录转移到地图中,并按alt字段键入:

 import form from './json/form.json'
 import config from './json/errors.json'

 const formByField = form.reduce(
   (total, field) => ({...total, [field.alt]: field}),
   {}
 );
 const configByField = config.reduce(
   (total, field) => ({...total, [field.alt]: field}),
   {}
 );

 // then you can merge two Maps together

 const result = new Map().mergeDeep(fromJS(formByField), fromJS(configByField));

请注意,您还要使用mergeDeep对每个匹配的密钥进行递归