繁体   English   中英

使用 lodash 在 javascript 中比较两个深度嵌套的数组

[英]Compare two deeply nested arrays in javascript using lodash

我有两个数组如下:

const initBlocks = [
    {
        closingDays: [
            {start: '01/10/2020', stop: '10/10/2020', type: 'workplace', reference: '', uuid: ''}
        ],
        openingsHours: [
            { start: '07:00', stop: '12:30', type: 'workplace', day: 'mon', reference: '', uuid: ''}
            { start: '07:00', stop: '12:30', type: 'workplace', day: 'tue', reference: '', uuid: ''}
        ],
        order: 0,
        reference: "123"
    }
    {
        openingsHours: [
            {start: '07:00', stop: '12:30', type: 'workplace', day: 'mon', reference: '', uuid: ''}
        ],
        order: 0,
        reference: "123"
    }
]

第二个:

 const blocks = [
    {
        closingDays: [
            {start: '01/10/2020', stop: '10/10/2020', type: 'workplace', reference: '', uuid: ''}
        ],
        openingsHours: [
            { start: '07:00', stop: '12:30', type: 'workplace', day: 'mon', reference: '', uuid: ''}
            { start: '07:00', stop: '12:30', type: 'showroom', day: 'tue', reference: '', uuid: ''}
        ],
        order: 0,
        reference: "123"
    }
    {
        openingsHours: [
            {start: '07:00', stop: '12:30', type: 'workplace', day: 'mon', reference: '', uuid: ''}
            {start: '07:00', stop: '12:30', type: 'workplace', day: 'mon', reference: '', uuid: ''}
        ],
        order: 1,
        reference: "321"
    }
]

我想比较这两个,我想看看openingsHours是否相同。 数组中可以有更多的对象,那么属性(开始、停止、类型和日期)可以不同。

我试过如下:

let areEqual = true;
filter(blocks, block => {
    return filter(initBlocks, initBlock => {
        const blockHours = block.openingsHours.map(item => { return { ...omit(item, ['reference', 'uuid']) } })
        const initBlockHours = initBlock.openingsHours.map(item => { return { ...omit(item, ['reference', 'uuid']) } })
        if(!isEqual(blockHours, initBlockHours)){
            areEqual = false
        }
    })
})

但是areEqual的结果不是它应该的样子。 它们不一样,因此它应该是false ,但我正在变得true 任何的想法?

正如评论中所建议的,您应该从areEqual设置为false 然后,我们只在有相等的值时才改变它,如果相等,我们立即返回。

const { filter, isEqual, omit } = require( "lodash" );
const initBlocks = [
  {
    closingDays: [
      {
        start: "01/10/2020",
        stop: "10/10/2020",
        type: "workplace",
        reference: "",
        uuid: ""
      }
    ],
    openingsHours: [
      {
        start: "07:00",
        stop: "12:30",
        type: "workplace",
        day: "mon",
        reference: "",
        uuid: ""
      },
      {
        start: "07:00",
        stop: "12:30",
        type: "workplace",
        day: "tue",
        reference: "",
        uuid: ""
      }
    ],
    order: 0,
    reference: "123"
  },
  {
    openingsHours: [
      {
        start: "07:00",
        stop: "12:30",
        type: "workplace",
        day: "mon",
        reference: "",
        uuid: ""
      }
    ],
    order: 0,
    reference: "123"
  }
];
const blocks = [
  {
    closingDays: [
      {
        start: "01/10/2020",
        stop: "10/10/2020",
        type: "workplace",
        reference: "",
        uuid: ""
      }
    ],
    openingsHours: [
      {
        start: "07:00",
        stop: "12:30",
        type: "workplace",
        day: "mon",
        reference: "",
        uuid: ""
      },
      {
        start: "07:00",
        stop: "12:30",
        type: "showroom",
        day: "tue",
        reference: "",
        uuid: ""
      }
    ],
    order: 0,
    reference: "123"
  },
  {
    openingsHours: [
      {
        start: "07:00",
        stop: "12:30",
        type: "workplace",
        day: "mon",
        reference: "",
        uuid: ""
      },
      {
        start: "07:00",
        stop: "12:30",
        type: "workplace",
        day: "mon",
        reference: "",
        uuid: ""
      }
    ],
    order: 1,
    reference: "321"
  }
];

let areEqual = false;

filter( blocks, block => {
  return filter( initBlocks, initBlock => {
    const blockHours = block.openingsHours.map( item => {
      return { ...omit( item, [ "reference", "uuid" ] ) };
    } );

    const initBlockHours = initBlock.openingsHours.map( item => {
      return { ...omit( item, [ "reference", "uuid" ] ) };
    } );
    
    if ( isEqual( blockHours, initBlockHours ) ) {
      areEqual = true;
      return;
    }
  } );
} );

console.log(areEqual);

如果数组内的顺序在比较中很重要,你应该这样做:

const check = initBlocks
  .map((b, idx) => {
    const _bOpeningHours = [...b.openingsHours];
    delete _bOpeningHours.reference;
    delete _bOpeningHours.uuid;
    const _blocksOpeningHours = [...blocks[idx].openingsHours];
    delete _blocksOpeningHours.reference;
    delete _blocksOpeningHours.uuid;
    return lodash.isEqual(_bOpeningHours, _blocksOpeningHours);
  })
  .every((c) => !!c);

代码沙盒链接

如果顺序无关紧要,您应该为您比较的每个数组将两个数组的开放时间分组在一个数组中,然后对它们进行排序并使用 isEqual 来获得结果:

const _initBlocks = initBlocks.map(b => b.openingHours).sort()
const _blocks = blocks.map(b => b.openingHours).sort()

const result = lodash.isEqual(_initBlocks, _blocks);

注意:不要按原样使用 sort(),因为 openingHours 包含 Objets。 使用自定义 sort() 函数根据您想要的值对它们进行排序。 否则 isEqual() 将考虑元素的顺序。 openHours 内的对象也是如此,您也应该对它们进行排序。

您可以尝试消除重复项并使用具有必要值的自定义格式,而不是检查所有内部对象。

为了比较,我使用以下格式:

{
  "workplace|mon": "07:00|12:30",
  "workplace|tue": "07:00|12:30"
}

一旦处理获得必要的值,您就可以使用 lodash 的isEqual检查相等性并返回它

 function getTypeBasedHours(array) { return array.reduce((acc, item) => { item.openingsHours.forEach((workDetails) => { const key = `${workDetails.type}|${workDetails.day}`; acc[key] = `${workDetails.start}|${workDetails.stop}` }) return acc }, {}) } const initBlocks=[{closingDays:[{start:"01/10/2020",stop:"10/10/2020",type:"workplace",reference:"",uuid:""}],openingsHours:[{start:"07:00",stop:"12:30",type:"workplace",day:"mon",reference:"",uuid:""},{start:"07:00",stop:"12:30",type:"workplace",day:"tue",reference:"",uuid:""}],order:0,reference:"123"},{openingsHours:[{start:"07:00",stop:"12:30",type:"workplace",day:"mon",reference:"",uuid:""}],order:0,reference:"123"}]; const blocks=[{closingDays:[{start:"01/10/2020",stop:"10/10/2020",type:"workplace",reference:"",uuid:""}],openingsHours:[{start:"07:00",stop:"12:30",type:"workplace",day:"mon",reference:"",uuid:""},{start:"07:00",stop:"12:30",type:"showroom",day:"tue",reference:"",uuid:""}],order:0,reference:"123"},{openingsHours:[{start:"07:00",stop:"12:30",type:"workplace",day:"mon",reference:"",uuid:""},{start:"07:00",stop:"12:30",type:"workplace",day:"mon",reference:"",uuid:""}],order:1,reference:"321"}]; const map1 = getTypeBasedHours(initBlocks) const map2 = getTypeBasedHours(blocks) console.log(map1, map2) console.log(_.isEqual(map1, map2))
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js"></script>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM