比较嵌入式数组的值并获取目标值

时间:2019-02-05 20:36:39

标签: javascript arrays

我正在使用以下代码检查嵌入在另一个数组中的数组上的相等性:

const equal = take("services", compare(
  take("history", compare(
    (a, b) => a._id === b._id
  ))
))(obj, obj2);

这是在比较两个看起来像这样的文档:

const obj = {
  _id: 1,
  services: [
    {
      _id: 23,
      service: "serviceOne",
      history: [
        {
          _id: 33,
          stage: "stageOne"
        }
      ]
    },
        {
      _id: 24,
      service: "serviceTwo",
      history: [
        {
          _id: 44,
          stage: "stageOne"
        }
      ]
    },
  ]
};

const obj2 = {
  _id: 1,
  services: [
    {
      _id: 23,
      service: "serviceOne",
      history: [
        {
          _id: 33,
          stage: "stageOne"
        }
      ]
    },
        {
      _id: 24,
      service: "serviceTwo",
      history: [
        {
          _id: 45,
          stage: "stageTwo"
        },
        {
          _id: 44,
          stage: "stageOne"
        }
      ]
    },
  ]
};

以上工作正常。当我运行console.log('equal: ', equal)时,它会记录false,因为history数组的级别不同。

我现在要做的是挖掘出两个文件之间存在差异的“ services.service”的值。到目前为止,我尝试过的只是获得了“ history.stage”的价值:

const compare = cb => (a, b) => a.length === b.length && a.every((el, i) => cb(el, b[i]));
const take = (key, cb) => (a, b) => cb(a[key], b[key]);
const obj = {
  _id: 1,
  services: [{
      _id: 23,
      service: "serviceOne",
      history: [{
        _id: 33,
        stage: "stageOne"
      }]
    },
    {
      _id: 24,
      service: "serviceTwo",
      history: [{
        _id: 44,
        stage: "stageOne"
      }]
    },
  ]
};

const obj2 = {
  _id: 1,
  services: [{
      _id: 23,
      service: "serviceOne",
      history: [{
        _id: 33,
        stage: "stageOne"
      }]
    },
    {
      _id: 24,
      service: "serviceTwo",
      history: [{
          _id: 45,
          stage: "stageTwo"
        },
        {
          _id: 44,
          stage: "stageOne"
        }
      ]
    },
  ]
};
const targetService = take("services", compare(
  take("history", compare(
    (a, b) => {
      a._id === b._id;
      console.log(a);
    }
  ))
))(obj, obj2);
console.log(targetService);

在这种情况下,如何获得“ services.service”?根据此处的文档,我想返回serviceTwo,因为它是该元素中已更改的history数组。

1 个答案:

答案 0 :(得分:0)

如果要保留该功能模式,则可能需要添加一个and帮助器,以执行多个比较:

const compare = cb => (a, b) => a.length === b.length && a.every((el, i) => cb(el, b[i]));
const take = (key, cb) => (a, b) => cb(a[key], b[key]);
const and = (cb1, cb2) => (a, b) => cb1(a, b) && cb2(a, b);
const equals = (a, b) => a === b;

const equal = take("services", compare( 
  and(
   take("service", equals),
   take("history", compare(
     take("_id", equals)
   ))
  )
))(obj, obj2);

但是,如果您跳过功能性编程,并使它更易于阅读,则可能会更容易:

 const historyEquals = (a, b) =>
   a._id === b._id;

 const serviceEquals = (a, b) => 
    a.service === b.service &&
    a.history.length === b.history.length &&
    a.history.every((el, i) => historyEquals(el, b.history[i]));

 const objEquals = (a, b) =>
    a.services.length === b.services.length &&
    a.services.every((el, i) => serviceEquals(el, b.services[i]));