0

I have a JSON object that I'm trying to parse using Javascript, but it's a bit of a mess and I don't know the best way to achieve what I'm after. The JSON object is below:

{[null, "[{"name":"type","value":"mental health"},{"name":"question","value":"what is"}]", "[{"name":"type","value":"mental health"},{"name":"question","value":"what is"}]", "[{"name":"type","value":"mental health"},{"name":"question","value":"what is"}]", "[{"name":"type","value":"mental health"},{"name":"question","value":"what is"}]", "[{"name":"type","value":"mental health"},{"name":"question","value":"types"}]", "[{"name":"type","value":"mental health"},{"name":"question","value":"types"}]", "[{"name":"type","value":"mental health"},{"name":"…what is"},{"name":"condition","value":"phobias"}]", "[{"name":"type","value":"mental health"},{"name":"…what is"},{"name":"condition","value":"phobias"}]", "[{"name":"type","value":"mental health"},{"name":"question","value":"what is"}]", "[{"name":"type","value":"mental health"},{"name":"question","value":"what is"}]", "[{"name":"type","value":"help"}]", "[{"name":"type","value":"mental health"},{"name":"question","value":"what is"}]", "[{"name":"type","value":"mental health"},{"name":"question","value":"what is"}]", "[{"name":"type","value":"mental health"},{"name":"question","value":"what is"}]", "[{"name":"type","value":"mental health"},{"name":"question","value":"types"}]", "[{"name":"type","value":"mental health"},{"name":"question","value":"types"}]", "[{"name":"type","value":"help"}]", "[{"name":"type","value":"mental health"},{"name":"question","value":"what is"}]", "[{"name":"type","value":"mental health"},{"name":"question","value":"what is"}]", "[{"name":"type","value":"mental health"},{"name":"question","value":"types"}]", "[{"name":"type","value":"mental health"},{"name":"question","value":"types"}]", "[{"name":"type","value":"mental health"},{"name":"question","value":"what is"}]", "[{"name":"type","value":"mental health"},{"name":"question","value":"types"}]", "[{"name":"type","value":"mental health"},{"name":"question","value":"what is"}]", "[{"name":"type","value":"mental health"},{"name":"question","value":"types"}]", "[{"name":"type","value":"mental health"},{"name":"…what is"},{"name":"condition","value":"phobias"}]", "[{"name":"type","value":"mental health"},{"name":"…what is"},{"name":"condition","value":"phobias"}]", "[{"name":"type","value":"mental health"},{"name":"question","value":"what is"}]", "[{"name":"type","value":"mental health"},{"name":"question","value":"what is"}]", "[{"name":"type","value":"mental health"},{"name":"question","value":"types"}]", "[{"name":"type","value":"mental health"},{"name":"question","value":"types"}]", "[{"name":"type","value":"mental health"},{"name":"…s"},{"name":"condition","value":"schizophrenia"}]", "[{"name":"type","value":"mental health"},{"name":"…uses"},{"name":"condition","value":"depression"}]", "[{"name":"type","value":"mental health"},{"name":"…uses"},{"name":"condition","value":"depression"}]", "[{"name":"type","value":"mental health"},{"name":"…s"},{"name":"condition","value":"schizophrenia"}]", "[{"name":"type","value":"mental health"},{"name":"…ypes"},{"name":"condition","value":"depression"}]", "[{"name":"type","value":"mental health"},{"name":"…s"},{"name":"condition","value":"schizophrenia"}]", "[{"name":"type","value":"mental health"},{"name":"…s"},{"name":"condition","value":"schizophrenia"}]", "[{"name":"type","value":"mental health"},{"name":"…ypes"},{"name":"condition","value":"depression"}]", null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null]}

The end result I'm trying to get to is a count of the values. However, I also want to split out all of the values in each of the arrays that are contained within the object.

The best result I've been able to achieve so far is:

{
[{"name":"type","value":"mental health"},{"name":"question","value":"prevalence"},{"name":"condition","value":"depression"}]: 2,
[{"name":"type","value":"mental health"},{"name":"question","value":"related issues"},{"name":"condition","value":"depression"}]: 3,
[{"name":"type","value":"mental health"},{"name":"question","value":"types"}]: 7,
[{"name":"type","value":"mental health"},{"name":"question","value":"what is"},{"name":"condition","value":"anxiety"}]: 3,
[{"name":"type","value":"mental health"},{"name":"question","value":"what is"},{"name":"condition","value":"ocd"}]: 2,
[{"name":"type","value":"mental health"},{"name":"question","value":"what is"},{"name":"condition","value":"panic disorder"}]: 6,
[{"name":"type","value":"mental health"},{"name":"question","value":"what is"},{"name":"condition","value":"schizophrenia"}]: 1,
[{"name":"type","value":"mental health"},{"name":"question","value":"what is"}]: 8,
null: 19
}

However, the end result I'd like to get to is as follows:

{
"type": 32,
"mental health": 32,
"question": 32,
"condition": 17,
"prevalence": 2,
"related issues": 3,
"types": 7,
"what is": 20,
"depression": 5,
"anxiety": 3,
"OCD": 2,
"Panic Disorder": 6,
"Scizophrenia": 1,
null: 19
}

Essentially, I want to count all of the values in the key/value pairs but I'm not sure how to do this because of the structure of the object and also the null values as they are a different format to the values in the rest of the object.

5
  • 2
    It's not valid JSON. Are you able to correct it at the source? Commented Sep 5, 2019 at 13:47
  • Is it correct that you don't distinguish between name and value properties in the end, but you just want to list how often some values occur for either property? Commented Sep 5, 2019 at 13:47
  • The object is invalid syntax. You cannot use an array object as the key/name of a property for an object. Commented Sep 5, 2019 at 13:48
  • 1
    In fact you have two non related question here, how to parse broken JSON (you need parser or if the code always look the same try to use regex to transform it to proper JSON) and have to transform it the thing you want which is not clear how they both related. Commented Sep 5, 2019 at 13:53
  • Thank you for your comments everyone, I've had difficulty fixing the JSON at source as it's coming through Azure Data Factory which only seems to be able to parse JSON one level deep Commented Sep 5, 2019 at 13:59

3 Answers 3

1

I've taken the liberty to make your source data into a valid JS:

const src = [null, `[{"name":"type","value":"mental health"},{"name":"question","value":"what is"}]`,`[{"name":"type","value":"mental health"},{"name":"question","value":"what is"}]`, `[{"name":"type","value":"mental health"},{"name":"question","value":"what is"}]`, `[{"name":"type","value":"mental health"},{"name":"question","value":"what is"}]`, `[{"name":"type","value":"mental health"},{"name":"question","value":"types"}]`, `[{"name":"type","value":"mental health"},{"name":"question","value":"types"}]`, `[{"name":"type","value":"mental health"},{"name":"…what is"},{"name":"condition","value":"phobias"}]`, `[{"name":"type","value":"mental health"},{"name":"…what is"},{"name":"condition","value":"phobias"}]`, `[{"name":"type","value":"mental health"},{"name":"question","value":"what is"}]`,`[{"name":"type","value":"mental health"},{"name":"question","value":"what is"}]`, `[{"name":"type","value":"help"}]`, `[{"name":"type","value":"mental health"},{"name":"question","value":"what is"}]`,`[{"name":"type","value":"mental health"},{"name":"question","value":"what is"}]`, `[{"name":"type","value":"mental health"},{"name":"question","value":"what is"}]`, `[{"name":"type","value":"mental health"},{"name":"question","value":"types"}]`, `[{"name":"type","value":"mental health"},{"name":"question","value":"types"}]`, `[{"name":"type","value":"help"}]`, `[{"name":"type","value":"mental health"},{"name":"question","value":"what is"}]`, `[{"name":"type","value":"mental health"},{"name":"question","value":"what is"}]`, `[{"name":"type","value":"mental health"},{"name":"question","value":"types"}]`, `[{"name":"type","value":"mental health"},{"name":"question","value":"types"}]`, `[{"name":"type","value":"mental health"},{"name":"question","value":"what is"}]`,`[{"name":"type","value":"mental health"},{"name":"question","value":"types"}]`, `[{"name":"type","value":"mental health"},{"name":"question","value":"what is"}]`, `[{"name":"type","value":"mental health"},{"name":"question","value":"types"}]`, `[{"name":"type","value":"mental health"},{"name":"…what is"},{"name":"condition","value":"phobias"}]`, `[{"name":"type","value":"mental health"},{"name":"…what is"},{"name":"condition","value":"phobias"}]`, `[{"name":"type","value":"mental health"},{"name":"question","value":"what is"}]`, `[{"name":"type","value":"mental health"},{"name":"question","value":"what is"}]`, `[{"name":"type","value":"mental health"},{"name":"question","value":"types"}]`,`[{"name":"type","value":"mental health"},{"name":"question","value":"types"}]`, `[{"name":"type","value":"mental health"},{"name":"…s"},{"name":"condition","value":"schizophrenia"}]`, `[{"name":"type","value":"mental health"},{"name":"…uses"},{"name":"condition","value":"depression"}]`, `[{"name":"type","value":"mental health"},{"name":"…uses"},{"name":"condition","value":"depression"}]`, `[{"name":"type","value":"mental health"},{"name":"…s"},{"name":"condition","value":"schizophrenia"}]`, `[{"name":"type","value":"mental health"},{"name":"…ypes"},{"name":"condition","value":"depression"}]`, `[{"name":"type","value":"mental health"},{"name":"…s"},{"name":"condition","value":"schizophrenia"}]`, `[{"name":"type","value":"mental health"},{"name":"…s"},{"name":"condition","value":"schizophrenia"}]`, `[{"name":"type","value":"mental health"},{"name":"…ypes"},{"name":"condition","value":"depression"}]`, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null];

And here's a very somewhat-generic (handles nested structures) solution:

// map and parse JSON when applicable
const parsed = src.map( item => {
    if ( typeof item === "string" ) {
        try {
            return JSON.parse(item);
        } catch (err) {
            return item;
        }
    } else {
        return item;
    }
});

function isPlainObj ( obj ) {
    return typeof obj == "object" && obj.constructor == Object;
}

function walk ( value, acc ) {
    if ( Array.isArray(value) ) {
        value.forEach( value => walk(value, acc));
    } else if ( value && isPlainObj(value) ) {
        Object.values(value).forEach( value => {
            walk(value, acc );
        });
    } else {
        acc[value] = (acc[value] || 0) + 1;
    }

    return acc;
}

const out = parsed.reduce((acc, value) => {
    return walk(value, acc);
}, {});

console.log(out);

gives

{
  null: 18,
  type: 39,
  'mental health': 37,
  question: 25,
  'what is': 15,
  types: 10,
  '...what is': 4,
  condition: 12,
  phobias: 4,
  help: 2,
  '...s': 4,
  schizophrenia: 4,
  '...uses': 2,
  depression: 4,
  '...ypes': 2
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you @dwelle - I'll do some testing later to see if I can get it to work in my code
Just been testing and this works perfectly - a great solution, thank you!
0

It seems to be you want values count. There is not properly stringified, If so then you can do like this.

const newObj = {};

obj.array.map((r) => {
   if (!r) {
       (newObj['null']) ? newObj['null'] += 1 : newObj['null'] = 1;
   } else {
       const subArray = JSON.parse(r);
       if (Array.isArray(subArray)) {
           subArray.forEach((r) => {
               Object.values(r)
                   .forEach((v) => {
                       (newObj[v]) ? newObj[v] += 1 : newObj[v] = 1;
                   })
           })
       }
   }
});

console.log(newObj);

Comments

0

Ideally you want to change the JSON at source so that it's valid. Failing that here's a method that strips out the bad characters from the string and parses it. It then uses reduce to produce an object with the appropriate counts for each available object value.

const str = '{[null, "[{"name":"type","value":"mental health"},{"name":"question","value":"what is"}]", "[{"name":"type","value":"mental health"},{"name":"question","value":"what is"}]", "[{"name":"type","value":"mental health"},{"name":"question","value":"what is"}]", "[{"name":"type","value":"mental health"},{"name":"question","value":"what is"}]", "[{"name":"type","value":"mental health"},{"name":"question","value":"types"}]", "[{"name":"type","value":"mental health"},{"name":"question","value":"types"}]", "[{"name":"type","value":"mental health"},{"name":"…what is"},{"name":"condition","value":"phobias"}]", "[{"name":"type","value":"mental health"},{"name":"…what is"},{"name":"condition","value":"phobias"}]", "[{"name":"type","value":"mental health"},{"name":"question","value":"what is"}]", "[{"name":"type","value":"mental health"},{"name":"question","value":"what is"}]", "[{"name":"type","value":"help"}]", "[{"name":"type","value":"mental health"},{"name":"question","value":"what is"}]", "[{"name":"type","value":"mental health"},{"name":"question","value":"what is"}]", "[{"name":"type","value":"mental health"},{"name":"question","value":"what is"}]", "[{"name":"type","value":"mental health"},{"name":"question","value":"types"}]", "[{"name":"type","value":"mental health"},{"name":"question","value":"types"}]", "[{"name":"type","value":"help"}]", "[{"name":"type","value":"mental health"},{"name":"question","value":"what is"}]", "[{"name":"type","value":"mental health"},{"name":"question","value":"what is"}]", "[{"name":"type","value":"mental health"},{"name":"question","value":"types"}]", "[{"name":"type","value":"mental health"},{"name":"question","value":"types"}]", "[{"name":"type","value":"mental health"},{"name":"question","value":"what is"}]", "[{"name":"type","value":"mental health"},{"name":"question","value":"types"}]", "[{"name":"type","value":"mental health"},{"name":"question","value":"what is"}]", "[{"name":"type","value":"mental health"},{"name":"question","value":"types"}]", "[{"name":"type","value":"mental health"},{"name":"…what is"},{"name":"condition","value":"phobias"}]", "[{"name":"type","value":"mental health"},{"name":"…what is"},{"name":"condition","value":"phobias"}]", "[{"name":"type","value":"mental health"},{"name":"question","value":"what is"}]", "[{"name":"type","value":"mental health"},{"name":"question","value":"what is"}]", "[{"name":"type","value":"mental health"},{"name":"question","value":"types"}]", "[{"name":"type","value":"mental health"},{"name":"question","value":"types"}]", "[{"name":"type","value":"mental health"},{"name":"…s"},{"name":"condition","value":"schizophrenia"}]", "[{"name":"type","value":"mental health"},{"name":"…uses"},{"name":"condition","value":"depression"}]", "[{"name":"type","value":"mental health"},{"name":"…uses"},{"name":"condition","value":"depression"}]", "[{"name":"type","value":"mental health"},{"name":"…s"},{"name":"condition","value":"schizophrenia"}]", "[{"name":"type","value":"mental health"},{"name":"…ypes"},{"name":"condition","value":"depression"}]", "[{"name":"type","value":"mental health"},{"name":"…s"},{"name":"condition","value":"schizophrenia"}]", "[{"name":"type","value":"mental health"},{"name":"…s"},{"name":"condition","value":"schizophrenia"}]", "[{"name":"type","value":"mental health"},{"name":"…ypes"},{"name":"condition","value":"depression"}]", null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null]}';

// Replace the failing quotes
const newstr = str.replace(/"\[|\]"/g, '');

// Remove the first and last characters to make the JSON parse, and parse it
const parsed = JSON.parse(newstr.substr(1, newstr.length - 2));

// `reduce` over the array
const result = parsed.reduce((acc, c) => {

  // If the current element isn't null and has a value property
  // extract the value and update the initial object
  if (c && c.value) {
    const { value } = c;
    acc[value] = (acc[value] || 0) + 1;
  }

  // Return the accumulator for the next iteration
  return acc;
}, {}); // <= initial object

console.log(result);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.