0

I put the same code also on jsbin: https://jsbin.com/literefeqo/edit?js,console

Explanation

I’ve got an array of objects (1) and would like to transform (possibly using map) this object. The transformation criteria is a given array (2) and corresponds to the german property in arrObj. That means, if there is a german property in arrObj it should be "copied" out and it should be used as a key to produce the resultObj (3). If there is no german property then a key should be "Unknown" or whatever.

Note: There can be more entries in resultObj for e.g. Montag. Thats way resultObj.Montag[i] should be an array of objects.

(1) Array of Objects

const arrObj = [
{
    "day": {
    "string": "Monday",
    "Number": 1
    },
    "description": {
    "type": "string",
    "value": "The first day of the week"
    },
    "german": {
    "type": "string",
    "value": "Montag"
    }
},
{
    "day": {
    "string": "Tuesday",
    "Number": 2
    },
    "description": {
    "type": "string",
    "value": "The second day of the week"
    }
},
{
    "day": {
    "string": "Wednesday",
    "Number": 3
    },
    "description": {
    "type": "string",
    "value": "The third day of the week"
    },
    "german": {
    "type": "string",
    "value": "Mittwoch"
    }
}
];

(2) Array that should become the key for the new object

const germanDays = ["Montag","Dienstag","Mittwoch","Donnerstag"];

(3) Result should look like

const resultObj =   {
"Montag": [
  {
    "day": {
      "string": "Monday",
      "Number": 1
    },
    "description": {
      "type": "string",
      "value": "The first day of the week"
    },
    "german": {
      "type": "string",
      "value": "Montag"
    }
  }
],
"Dienstag": [
  {}
],
"Mittwoch": [
  {
    "day": {
      "string": "Wednesday",
      "Number": 3
    },
    "description": {
      "type": "string",
      "value": "The third day of the week"
    },
    "german": {
      "type": "string",
      "value": "Mittwoch"
    }
  }
],
"Donnerstag": [
  {}
],
"Unknown": [
  {
    "day": {
      "string": "Tuesday",
      "Number": 2
    },
    "description": {
      "type": "string",
      "value": "The second day of the week"
    }
  }
]

};

2
  • 2
    And you know that object properties do not have order in JavaScript? Just checking... Commented Dec 3, 2018 at 13:59
  • I know. I don’t care about ordering. Commented Dec 3, 2018 at 14:00

2 Answers 2

3

(possibly using map)

map, is meant for Array to Array mapping, a more appropriate function is reduce.

Here is an example.

const germanDays = ["Montag","Dienstag","Mittwoch","Donnerstag"]

const arrObj = [
{
    "day": {
    "string": "Monday",
    "Number": 1
    },
    "description": {
    "type": "string",
    "value": "The first day of the week"
    },
    "german": {
    "type": "string",
    "value": "Montag"
    }
},
{
    "day": {
    "string": "Tuesday",
    "Number": 2
    },
    "description": {
    "type": "string",
    "value": "The second day of the week"
    }
},
{
    "day": {
    "string": "Wednesday",
    "Number": 3
    },
    "description": {
    "type": "string",
    "value": "The third day of the week"
    },
    "german": {
    "type": "string",
    "value": "Mittwoch"
    }
},
{
    "day": {
    "string": "Monday",
    "Number": 1
    },
    "description": {
    "type": "string",
    "value": "Just another text is here"
    },
    "german": {
    "type": "string",
    "value": "Montag"
    }
}
];

const ret = germanDays.reduce((a, v) => {
  const f = arrObj.filter(f => f.german && f.german.value === v);
  a[v] = f;
  return a;
}, {
  "Unknown": arrObj.filter(f => !f.german)
});


console.log(ret);

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

4 Comments

Very nice. However, it is skipping the case if information is there, as in Tuesday, but no german property is there. Since it should be pushed in a new prop "unknown" ... as in the example resultObj
You could just do an array.filter for this, and add to your result. Updated!!
Just figured out, that this approach fails, unfortunately, when there are more german props for an existing prop, e.g. Monday: jsbin.com/radowuqaca/edit?js,console
@Kalaschnik Oh, yes. Updated!! Just needed filter again instead of find.
2

Something like this (click the button "Run code snippet"):

const arrObj = [
{
    "day": {
    "string": "Monday",
    "Number": 1
    },
    "description": {
    "type": "string",
    "value": "The first day of the week"
    },
    "german": {
    "type": "string",
    "value": "Montag"
    }
},
{
    "day": {
    "string": "Tuesday",
    "Number": 2
    },
    "description": {
    "type": "string",
    "value": "The second day of the week"
    }
},
{
    "day": {
    "string": "Wednesday",
    "Number": 3
    },
    "description": {
    "type": "string",
    "value": "The third day of the week"
    },
    "german": {
    "type": "string",
    "value": "Mittwoch"
    }
}
];


const germanDays = ["Montag", "Dienstag", "Mittwoch", "Donnerstag"];

const resultObj = {}

for (const item of arrObj) {
    if (item.german && item.german.value && germanDays.includes(item.german.value)) {
        addVal(item.german.value, item)
    } else {
        addVal('unknown', item)
    }
}

// helper func
function addVal(key, val) {
    if(!resultObj[key]) {
        resultObj[key] = []
    }
    resultObj[key].push(val)
}

console.log(resultObj)

2 Comments

Very nice. However, it is skipping the case if information is there, as in Tuesday, but no german property is there. Since it should be pushed in a new prop "unknown", as in the example resultObj
Although, Stackoverflow isn't for writing the whole code for you (but to give you a direction), fixed it and now it works according to your criteria.

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.