4

I've spent a couple hours to find a way to handling this array of objects:

[
  {
    "value": "foo01",
    "Diagnosis_Code": "Tidak ada",
    "name": "bar"
  },
  {
    "value": "foo02",
    "Diagnosis_Code": "Tidak ada",
    "name": "bar"
  },
  {
    "value": "foo03",
    "Diagnosis_Code": "Tidak ada",
    "name": "bar"
  },
  {
    "value": "foo04",
    "Diagnosis_Code": "Tidak ada",
    "name": "bar"
  },
  {
    "value": "val1",
    "Diagnosis_Code": "foo03",
    "name": "bar2"
  },
  {
    "value": "val2",
    "Diagnosis_Code": "foo01",
    "name": "bar2"
  },
  {
    "value": "val3",
    "Diagnosis_Code": "foo02",
    "name": "bar2"
  },
  {
    "value": "val3",
    "Diagnosis_Code": "foo04",
    "name": "bar2"
  },
  {
    "value": "val1",
    "Diagnosis_Code": "foo01",
    "name": "bar3"
  },
  {
    "value": "val2",
    "Diagnosis_Code": "foo03",
    "name": "bar3"
  },
  {
    "value": "val2",
    "Diagnosis_Code": "foo04",
    "name": "bar3"
  },
  {
    "value": "val3",
    "Diagnosis_Code": "foo02",
    "name": "bar3"
  },
  {
    "value": "val1",
    "Diagnosis_Code": "foo01",
    "name": "bar4"
  },
  {
    "value": "val1",
    "Diagnosis_Code": "foo02",
    "name": "bar4"
  },
  {
    "value": "val1",
    "Diagnosis_Code": "foo04",
    "name": "bar4"
  },
  {
    "value": "val2",
    "Diagnosis_Code": "foo03",
    "name": "bar4"
  }
]

My Expected JSON is something like this:

[
  {
    "name":"bar",
    "value":[
      {
        "value": "foo01",
        "Diagnosis_Code": ["Tidak ada"],
        "name": "bar",
      },
      {
        "value": "foo02",
        "Diagnosis_Code": ["Tidak ada"],
        "name": "bar",
      },
      {
        "value": "foo03",
        "Diagnosis_Code": ["Tidak ada"],
        "name": "bar",
      },
      {
        "value": "foo04",
        "Diagnosis_Code": ["Tidak ada"],
        "name": "bar",
      }
    ]
  },
  {
    "name": "bar2",
    "value": [
      {
        "value": "val1",
        "Diagnosis_Code": ["foo03"],
        "name": "bar2",
      },
      {
        "value": "val2",
        "Diagnosis_Code": ["foo01"],
        "name": "bar2",
      },
      {
        "value": "val3",
        "Diagnosis_Code": ["foo02", "foo04"],
        "name": "bar2",
      }
    ]
  },
  {
    "name": "bar3",
    "value":[
      {
        "value": "val1",
        "Diagnosis_Code": ["foo01"],
        "name": "bar3",
      },
      {
        "value": "val2",
        "Diagnosis_Code": ["foo03", "foo04"],
        "name": "bar3",
      },
      {
        "value": "val3",
        "Diagnosis_Code": ["foo02"],
        "name": "bar3",
      },
    ]
  },
  {
    "name": "bar4",
    "value": [
      {
        "value": "val1",
        "Diagnosis_Code": ["foo01", "foo02", "foo04"],
        "name": "bar4",
      },
      {
        "value": "val2",
        "Diagnosis_Code": ["foo03"],
        "name": "bar4",
      },
    ]
  },
]

I want to put duplicate name value into Object and if the Diagnosis_Code of json is same as another value, put it into an array

The code I've use for now is just to using reduce to handle the name, but I don't know how to handle the Diagnosis_Code property:

var orgArray = [{"value":"foo01","Diagnosis_Code":"Tidak ada","name":"bar"},{"value":"foo02","Diagnosis_Code":"Tidak ada","name":"bar"},{"value":"foo03","Diagnosis_Code":"Tidak ada","name":"bar"},{"value":"foo04","Diagnosis_Code":"Tidak ada","name":"bar"},{"value":"val1","Diagnosis_Code":"foo03","name":"bar2"},{"value":"val2","Diagnosis_Code":"foo01","name":"bar2"},{"value":"val3","Diagnosis_Code":"foo02","name":"bar2"},{"value":"val3","Diagnosis_Code":"foo04","name":"bar2"},{"value":"val1","Diagnosis_Code":"foo01","name":"bar3"},{"value":"val2","Diagnosis_Code":"foo03","name":"bar3"},{"value":"val2","Diagnosis_Code":"foo04","name":"bar3"},{"value":"val3","Diagnosis_Code":"foo02","name":"bar3"},{"value":"val1","Diagnosis_Code":"foo01","name":"bar4"},{"value":"val1","Diagnosis_Code":"foo02","name":"bar4"},{"value":"val1","Diagnosis_Code":"foo04","name":"bar4"},{"value":"val2","Diagnosis_Code":"foo03","name":"bar4"}];

var newArray = orgArray.reduce(function(acc, curr) {
  var findIfNameExist = acc.findIndex(function(item) {
    return item.name === curr.name;
  })
  if (findIfNameExist === -1) {
    let obj = {
      'name': curr.name,
      "value": [curr]
    }
    acc.push(obj)
  } else {
    acc[findIfNameExist].value.push(curr)
  }
  return acc;

}, []);
console.log(newArray)

Is there a way of handling transforming the duplicate Diagnosis_Codes into an array?

2 Answers 2

2

Here is another example!

First, I use reduce to reduce your object, then, I use map to remap it to get the expected format ;)

It may not be the best-performance way to do this, but I find it is the more maintainable and readable way though.

I hope this is clear and will help you :D

const input = [
  {
    "value": "foo01",
    "Diagnosis_Code": "Tidak ada",
    "name": "bar"
  },
  {
    "value": "foo02",
    "Diagnosis_Code": "Tidak ada",
    "name": "bar"
  },
  {
    "value": "foo03",
    "Diagnosis_Code": "Tidak ada",
    "name": "bar"
  },
  {
    "value": "foo04",
    "Diagnosis_Code": "Tidak ada",
    "name": "bar"
  },
  {
    "value": "val1",
    "Diagnosis_Code": "foo03",
    "name": "bar2"
  },
  {
    "value": "val2",
    "Diagnosis_Code": "foo01",
    "name": "bar2"
  },
  {
    "value": "val3",
    "Diagnosis_Code": "foo02",
    "name": "bar2"
  },
  {
    "value": "val3",
    "Diagnosis_Code": "foo04",
    "name": "bar2"
  },
  {
    "value": "val1",
    "Diagnosis_Code": "foo01",
    "name": "bar3"
  },
  {
    "value": "val2",
    "Diagnosis_Code": "foo03",
    "name": "bar3"
  },
  {
    "value": "val2",
    "Diagnosis_Code": "foo04",
    "name": "bar3"
  },
  {
    "value": "val3",
    "Diagnosis_Code": "foo02",
    "name": "bar3"
  },
  {
    "value": "val1",
    "Diagnosis_Code": "foo01",
    "name": "bar4"
  },
  {
    "value": "val1",
    "Diagnosis_Code": "foo02",
    "name": "bar4"
  },
  {
    "value": "val1",
    "Diagnosis_Code": "foo04",
    "name": "bar4"
  },
  {
    "value": "val2",
    "Diagnosis_Code": "foo03",
    "name": "bar4"
  }
];

// Condensed/reduced object.
let output = input.reduce((accum, item) => {
  if(!accum[item.name]) {
    accum[item.name] = {};
  }
  if(!accum[item.name][item.value]) {
    accum[item.name][item.value] = [];
  }
  accum[item.name][item.value].push(item.Diagnosis_Code);
  accum[item.name][item.value].original = item;
  return accum;
}, {});

// Object remapped to fit your expected format.
output = Object.keys(output).map((itemName) => {
  return {
    'name': itemName,
    'value': Object.keys(output[itemName]).map((valueName) => {
    const patchedOriginalItem = output[itemName][valueName].original;
    patchedOriginalItem['Diagnosis_Code'] = output[itemName][valueName];
      return patchedOriginalItem;
    })
  };
});

console.log(output);

Sign up to request clarification or add additional context in comments.

5 Comments

i can't do that, because the value[index].value will be dynamically
I'm afraid I don't understand the problem, can you be more precise? I mean, what's going to be dynamic? You have a static object, you want to transform it in another format.
your return inside value arrays is harcoded, with name, value, and Diagnosis_Code keys, but how can i handle those array if I have more than 3 object inside arrays, so I need to declared the others too, right?
Hmm ok, I get it, you want the exact original object! I'm going to edit :)
Here it is :) I'm just patching the Diagnosis_Code attribute to get the condensed array version ;)
1

Use .reduce to convert the array into an object, as you're doing, but then you need to .find twice to see if the matching name and then if the matching value object exists. find (or .findIndex) just once won't be enough.

const input = [
  {
    "value": "foo01",
    "Diagnosis_Code": "Tidak ada",
    "name": "bar"
  },
  {
    "value": "foo02",
    "Diagnosis_Code": "Tidak ada",
    "name": "bar"
  },
  {
    "value": "foo03",
    "Diagnosis_Code": "Tidak ada",
    "name": "bar"
  },
  {
    "value": "foo04",
    "Diagnosis_Code": "Tidak ada",
    "name": "bar"
  },
  {
    "value": "val1",
    "Diagnosis_Code": "foo03",
    "name": "bar2"
  },
  {
    "value": "val2",
    "Diagnosis_Code": "foo01",
    "name": "bar2"
  },
  {
    "value": "val3",
    "Diagnosis_Code": "foo02",
    "name": "bar2"
  },
  {
    "value": "val3",
    "Diagnosis_Code": "foo04",
    "name": "bar2"
  },
  {
    "value": "val1",
    "Diagnosis_Code": "foo01",
    "name": "bar3"
  },
  {
    "value": "val2",
    "Diagnosis_Code": "foo03",
    "name": "bar3"
  },
  {
    "value": "val2",
    "Diagnosis_Code": "foo04",
    "name": "bar3"
  },
  {
    "value": "val3",
    "Diagnosis_Code": "foo02",
    "name": "bar3"
  },
  {
    "value": "val1",
    "Diagnosis_Code": "foo01",
    "name": "bar4"
  },
  {
    "value": "val1",
    "Diagnosis_Code": "foo02",
    "name": "bar4"
  },
  {
    "value": "val1",
    "Diagnosis_Code": "foo04",
    "name": "bar4"
  },
  {
    "value": "val2",
    "Diagnosis_Code": "foo03",
    "name": "bar4"
  }
];

const output = input.reduce((accum, item) => {
  const { name } = item;
  let foundNameObj = accum.find(({ name: findName }) => findName === name);
  if (!foundNameObj) {
    foundNameObj = { name, value: [] };
    accum.push(foundNameObj);
  }
  const foundValObj = foundNameObj.value.find(({ value }) => value === item.value);
  if (!foundValObj) {
    // value hasn't appeared before, we can just push the item:
    foundNameObj.value.push({...item, Diagnosis_Code: [item.Diagnosis_Code] });
    return accum;
  }
  foundValObj.Diagnosis_Code.push(item.Diagnosis_Code);
  return accum;
}, [])
console.log(output);

Don't mix var and let/const - if you're using ES6, which you should be, always use const, except when you need to reassign, in which case use let. (var is hoisted and has function scope rather than block scope, which is unintuitive and can lead to unexpected bugs)

5 Comments

but how do you handle Diagnosis_Code to be an array even there's just have 1 value?
Oh, I thought they stayed as individual strings when there was only one item because I was scrolled to the bottom. Under what conditions do they turn into arrays rather than strings when there's just one value?
though there's no conditions about Diagnosis_Code, it should be an array if there's only have one or more value
Please fix your My Expected JSON then, because it has strings.
sorry about it, I'm not realized it's not completed edit, but your code should work, thanks anyway

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.