簡體   English   中英

如果匹配公共值,則Vanilla Javascript將JSON數組對象合並到嵌套數組中

[英]Vanilla Javascript merge JSON array objects into nested array if match a common value

我找不到與我要解決的問題相同的解決方案。 如果重復,請提供指向解決方案的鏈接。

使用原始Javascript,合並具有共同值的對象數組。 我有一個JSON文件,它將創建以下javascript對象(我無法更改原始結構)。 請注意,每個對象將具有不同的嵌套名稱和嵌套值。 但是,通用值是名稱[0]

var data = [
  {
    name: [
      'Data 1', // common value
      '1 Jan, 2019', // same value therefore not overwrite/merge
      'hotfix dec'
    ],
    value: [
      'hotfix1.fsfix',
      'hotfix1.txt'
    ]
  },
  {
    name: [
      'Data 1', // common value
      '1 Jan, 2019' // same value therefore not overwrite/merge
    ],
    value: 'data1.jar'
  },
  {
    name: [
      'Data 2',
      '1 Feb, 2019'
    ],
    value: 'data2.fsfix'
  },
  {
    name: [
      'Data 2',
      '1 Feb, 2019'
    ],
    value: 'data2.jar'
  },
  {
    name: [
      'Data 3',
      '1 Mar, 2018'
    ],
    value: 'data3.fsfix'
  }
]

期望輸出將合並具有相同名稱[0]的嵌套對象。

var data = [
  {
    name: [
      'Data 1', // common value
      '1 Jan, 2019', // same value therefore not overwrite/merge
      'hotfix dec'
    ],
    value: [
      'data1.fsfix',
      'data1.txt',
      'data1.jar' // This was added after the merge
    ]
  },
  {
    name: [
      'Data 2',
      '1 Feb, 2019'
    ],
    value: [
      'data2.fsfix',
      'data2.jar' // This was added after the merge
    ]
  },
  {
    name: [
      'Data 3',
      '1 Mar, 2018'
    ],
    value: 'data3.fsfix'
  }
]

使用這種新的合並結構,我將創建一個函數來循環每個數組集。 提前致謝

您可以使用地圖通過名字輸入數據。 然后將數據填充到對應Map值內的value屬性中,還收集name數組中的所有額外值(除了前兩個條目之外),最后提取Map值。

這適用於線性時間復雜度:

 var data = [{name: ['Data 1', '1 Jan, 2019', 'hotfix dec'],value: ['hotfix1.fsfix','hotfix1.txt']},{name: ['Data 1', '1 Jan, 2019'],value: 'data1.jar'},{name: ['Data 2','1 Feb, 2019'],value: 'data2.fsfix'},{name: ['Data 2','1 Feb, 2019'],value: 'data2.jar'},{name: ['Data 3','1 Mar, 2018'],value: 'data3.fsfix'}]; const map = new Map(data.map(o => [o.name[0], { name: o.name.slice(0,2), value: [] }])); data.forEach(o => map.get(o.name[0]).value.push(...[].concat(o.value))); data.forEach(o => map.get(o.name[0]).name.push(...o.name.slice(2))); const result = Array.from(map.values(), o => o.value.length === 1 ? { ...o, value: o.value[0] } : o); console.log(result); 

傳遞給Array.from的回調函數是一個映射函數。 僅需要將只有一個字符串的值數組轉換為該字符串。 如果這不是必需的,則可以省略該回調,而只需執行Array.from(map.values())

使用某些Array方法,我認為您可以完成這項工作(下面的未經測試的代碼,但是我認為它應該做您想要的事情):

// Merge matching entries by pushing values from matching objects to each other
data = data.map(entry => {
    let matchingObjects = data.filter(match => {
        return match.name[0] === entry.name[0];
    });
    matchingObjects.forEach(match => {
        if (match !== entry) {
            var flatValue = [entry.value].flat();
            entry.value = flatValue.push.apply(flatValue, [match.value].flat());
        }
    });
});

// Remove duplicates by filtering out all but the first entry of each name[0]
data = data.filter((entry, index) => {
    return index === data.findIndex(match => {
        return match.name[0] === entry.name[0];
    });
});

您還可以使用reducemap創建所需的結果。 我認為總體而言,這是一個非常強大的組合。

    const data = [{name: ['Data 1', '1 Jan, 2019', 'hotfix dec'],value: ['hotfix1.fsfix','hotfix1.txt']},{name: ['Data 1', '1 Jan, 2019'],value: 'data1.jar'},{name: ['Data 2','1 Feb, 2019'],value: 'data2.fsfix'},{name: ['Data 2','1 Feb, 2019'],value: 'data2.jar'},{name: ['Data 3','1 Mar, 2018'],value: 'data3.fsfix'}];

    const dataMap = data.reduce((acc, curr)=>{
        id = curr.name[0];
        acc[id] = acc[id] || {
            name: [],
            value: []
        };
        const value = Array.isArray(curr.value) ? curr.value : [curr.value]

        acc[id].name = [...acc[id].name, ...curr.name.filter((i)=>acc[id].name.indexOf(i)===-1)]
        acc[id].value = [...acc[id].value, ...value.filter((i)=>acc[id].value.indexOf(i)===-1)]

        return acc
    },{})
    const result = Object.keys(dataMap).map(key=> {
        const d = dataMap[key];
        d.value = d.value.length===1 ? d.value[0] : d.value
        return d;
    })

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM