删除JSON键值,如果对象里面的值之前存在

remove JSON key value, if the value inside the object exists before

所以,我有一个 json 对象,其中的键是随机的,值有时会重复。我需要找到一种方法来使用键删除重复的值。如果它是一个 json 数组,我需要从 json 数组中删除一个特定的值。 例如,如果我的 JSON 文件如下:

  {
  "modelhelloamazingIssue": {
    "modelhelloamazingIssueSevere": {
      "nameText": "Name",
      "helloAnalysisType": [
        "Normal",
        "Mild",
        "Moderate",
        "Severe"
      ],
      "helloText": "hello",
      "abouthellosolo": "hello solo is a serious hello disorder that causes you to stop amazing during hello. It's important to understand the signs and symptoms.",
      "noteText": "This is not a medical diagnosis and you may want to talk to your doctor.",
      "buttonText0": "Next steps"
    },
    "modelhelloamazingIssueMild": {
      "nameText": "Name Example",
      "helloAnalysisType": [
        "Normal",
        "Mild",
        "Moderate",
        "Severe"
      ],
      "helloText": "hello",
      "abouthellosolo": "My god this is so cool.",
      "noteText": "This is not a medical diagnosis and you may want to talk to your doctor.",
      "buttonText1": "Next steps"
    }
  }
}

我创建的新 JSON 文件的预期输出将是这样的。

{
  "modelhelloamazingIssue": {
    "modelhelloamazingIssueSevere": {
      "nameText": "Name",
      "helloAnalysisType": [
        "Normal",
        "Mild",
        "Moderate",
        "Severe"
      ],
      "helloText": "hello",
      "abouthellosolo": "hello solo is a serious hello disorder that causes you to stop amazing during hello. It's important to understand the signs and symptoms.",
      "noteText": "This is not a medical diagnosis and you may want to talk to your doctor.",
      "buttonText0": "Next steps"
    },
    "modelhelloamazingIssueMild": {
      "nameText": "Name Example",
      "abouthellosolo": "My god this is so cool."
    }
  }
}

到目前为止,我已经在我的 javascript 中尝试了以下方法,我不知道存在哪些键,因此我需要单独解析它们。我无法写入预期的输出文件。我能够找到重复值,但不确定如何将其从文件中删除。 我正在使用 删除键 但它仍然没有从文件中删除。

const fs = require('fs');
var array = [];


function parse() {
    let json = require('/home/ashutosh/Downloads/latest-night-strings.json')
    var keys = Object.keys(json)
    getAllValues(keys, json)


    let data = JSON.stringify(json);
    fs.writeFileSync('/home/ashutosh/Desktop/awesome.json', data);
    console.log(data)
    // print(json)

}


function getAllValues(key, jsonObject) {

    for (var i = 0; i < key.length; i++) {
        console.log(typeof jsonObject[key[i]] == 'object');

        if (typeof jsonObject[key[i]] == 'object') {

            let myAnotherObject = jsonObject[key[i]]
            var keys = Object.keys(myAnotherObject)
            getAllValues(keys, myAnotherObject)
        }

        if (typeof jsonObject[key[i]] == 'string') {

            if (array.includes(jsonObject[key[i]])) {

                //    Already contains the value so delete the json key value from the file...

                console.log("deleting duplicate keys" + key[i] + " with value" + jsonObject[key[i]]);
                //"noteText": "This is not a medical diagnosis and you may want to talk to you doctor.",
                var isDeleteSuccess = delete key[i]
                console.log("isDeleteSuccess " + isDeleteSuccess)


            } else {

                array.push(jsonObject[key[i]])
            }

            console.log(jsonObject[key[i]]);

        }
    }
}

parse()

Update: OP doesn't care about keys, so to just remove duplicate values, and then of course the associated key, below is an example using Set's.

更新了下面的工作代码段 ->

const data = {"modelhelloamazingIssue":{"modelhelloamazingIssueSevere":{"nameText":"Name","helloAnalysisType":["Normal","Mild","Moderate","Severe"],"helloText":"hello","abouthellosolo":"hello solo is a serious hello disorder that causes you to stop amazing during hello. It's important to understand the signs and symptoms.","noteText":"This is not a medical diagnosis and you may want to talk to your doctor.","buttonText0":"Next steps"},"modelhelloamazingIssueMild":{"nameText":"Name Example","helloAnalysisType":["Normal","Mild","Moderate","Severe"],"helloText":"hello","abouthellosolo":"My god this is so cool.","noteText":"This is not a medical diagnosis and you may want to talk to your doctor.","buttonText1":"Next steps"}}};

function removeDuplicateValues(obj) {
  const dups = new Set();
  function inner(o) {
    const needSplice = [];
    for (const [k, v] of Object.entries(o)) {     
      if (typeof v === 'object') {
        inner(v);
        if (!Object.keys(v).length) delete(o[k]);
      } else {
        if (dups.has(v)) {
          if (Array.isArray(o)) needSplice.unshift(k);
          else delete o[k];
        }
        else dups.add(v);
      }
    }
    for (const i of needSplice) o.splice(i, 1);
  }
  inner(obj);
}


removeDuplicateValues(data);

console.log(data);

我会在这里保留检查键和值的原始版本,它可能对其他用户搜索有用..

您有两个不同的键 buttonText0buttonText1,因此根据您的逻辑,这些键也应该出现,但在您的示例中不包括它。

但假设你的逻辑是正确的,而你的示例输出是错误的。

这样做的一种方法是将对象展平为地图.. 例如。 {a:{b:4}} 变为 key: 'a.b', value: 4,同时进行重复检查。最后将其扩展为您期望的对象。

示例..

var data = {"modelhelloamazingIssue":{"modelhelloamazingIssueSevere":{"nameText":"Name","helloAnalysisType":["Normal","Mild","Moderate","Severe"],"helloText":"hello","abouthellosolo":"hello solo is a serious hello disorder that causes you to stop amazing during hello. It's important to understand the signs and symptoms.","noteText":"This is not a medical diagnosis and you may want to talk to your doctor.","buttonText0":"Next steps"},"modelhelloamazingIssueMild":{"nameText":"Name Example","helloAnalysisType":["Normal","Mild","Moderate","Severe"],"helloText":"hello","abouthellosolo":"My god this is so cool.","noteText":"This is not a medical diagnosis and you may want to talk to your doctor.","buttonText1":"Next steps"}}};

const gotKey = new Map();

function flat(o, root) {
  let ret = [];
  for (const [k, v] of Object.entries(o)) {
    if (typeof v === 'object' && !Array.isArray(v)) ret = [...ret, ...flat(v, root + k + '.')];
    else {
      const e = gotKey.get(k);
      if (!e || JSON.stringify(e) !== JSON.stringify(v)) {
        gotKey.set(k, v);
        ret.push([root + k, v]);
      }
    }
  }
  return ret;
}

const f = flat(data, '.');

const newObj = {};

for (const [k, v] of f) {
  const splits = k.split('.').filter(Boolean);
  let o = newObj;
  for (let ix = 0; ix < splits.length; ix ++)  {
    const s = splits[ix];
    if (ix === splits.length -1) o[s] = v;
    else {
      if (!o[s]) o[s] = {};
      o = o[s];
    }
  }
}


console.log(newObj);