Get property value from an object inside of an array - javascript

I'm trying to grab class code property value from the object inside each array belonging to "class". (I'm aware my data is convoluted).
This is my student array:
student = [
{"class":[{
"code":"PSJ001",
"professor":"McHale",
"description":"course description"}]
},
{"class":[{
"code":"ENG303",
"professor":"Dench",
"description":"course description"}]
},
{"class":[{
"code":"SCI003",
"professor":"Biju",
"description":"course description"}]
}
]
What I'm trying to get is...
['PSJ001','ENG303','SCI003']
This is what I have...
let classCodes = [];
for (const i in student) {
classCodes = classCodes.concat(student[i].map(obj => {
return obj.code;
}));
}
What am I doing wrong here? (written in jsx)

You can use map() to get desired result
var student = [{"class":[{"code":"PSJ001","professor":"McHale","description":"course description"}]},{"class":[{"code":"ENG303","professor":"Dench","description":"course description"}]},{"class":[{"code":"SCI003","professor":"Biju","description":"course description"}]}];
var result = student.map(function(e) {
return e.class[0].code;
});
console.log(result)

Basically this will work reliable:
student.map(o => o.class.map(c => c.code)).reduce((obj, arr) => arr.push(...obj) && arr, []);
First we use .map() to get the classes, and inside we use .map() again to get the codes. This gives us a array of arrays. Then we use .reduce() to flatten that array.

Related

Converting arrays nested in array into object using forEch (does not work somehow?)

I am having trouble with something i thought it will be simple.
I have an array of nested arrays with strings.
const cities = [['Vienna'],['Berlin'],['London'],['Oslo'],['New York']]
I must convert these nested arrays into objects. I think forEach method should suit perfectly along with Object.assign.
I written something like these:
function convert(element) {
Object.assign({}, element)
}
const Test = cities.forEach(convert)
But then i am getting from console.log(Test) undefinded. Why so ? I am iterating through the whole array and each of her arrays should be assign as object. Whats missing ?
Object should contain key: value pair
If you want to convert each string element into an object element. Then you can do something like this :
const cities = [['Vienna'],['Berlin'],['London'],['Oslo'],['New York']]
const res = cities.map((item) => {
return {
city: item[0]
}
});
console.log(res);

Issue sorting by date with lodash

I'm trying to have a sorted list of items by data using lodash and vue moments, I'm using a computed property but for some reason this computed property named sortByUsedDate returns a number instead of a sorted array... it's returning 11 exactly.
This is my code:
sortByUsedDate: function(){
let sortedCodes = _.orderBy(this.modalPayload.discountcodes, (code) => {
return Vue.moment(code.usedDate).format('MDYYYY');
}, ['desc']);
let sortedWithoutUnused = _.remove(sortedCodes, function(code) {
return code.isBought === 1;
});
let unusedCodes = _.filter(this.modalPayload.discountcodes, function(code){
return code.isBought == 0;
});
let final = sortedWithoutUnused.push(unusedCodes);
return final;
}
.push returns the length of the array. You should just return the array without the assignment:
sortedWithoutUnused.push(unusedCodes);
return sortedWithoutUnused;
But if you're trying to combine two arrays, I don't think you want to use push anyway, you'll probably want to use ... or .concat instead:
return [...sortedWithoutUnused, ...unusedCodes];
Or
return sortedWithoutUnused.concat(unusedCodes);

How to omit a particular key while pushing json objects to an array?

So, I have a JSON array of objects , which in turn contains other arrays of objects. This array of objects has no particular fixed structure as such so its very difficult for me do something like delete mainArray[0].obj.subobj[1].objToOmit;
So I have a key/object called possibleAnswers which I need to remove/omit. In my program I am pushing the contents of one array into another array. So while I am pushing the contents of first array of objects into another, I need to omit the possibleAnswers object from being pushed.
Is there any way or function that searches an array of objects and helps me omit the necessary key? Or what would be a solution as per your thoughts?
Example :
Here is a minimal example: https://codebeautify.org/jsonviewer/cb9fea0d
Edit: In the above JSON there is a key called possibleMembers which is wrong. its possibleAnswers
var collectObservationsFromConceptSets = function () {
$scope.consultation.observations = [];
_.each($scope.consultation.selectedObsTemplates, function (conceptSetSection) {
if (conceptSetSection.observations) {
_.each(conceptSetSection.observations, function (obs) {
$scope.consultation.observations.push(obs);
});
}
});
}
In the above code while pushing the object into another array, how can I omit the possibleAnswers keys? Is there a way to omit?
Thanks a lot people! Both the answers are correct and have generated the exact correct output. Unfortunately I can only select 1 answer as correct and its going to be random.
This is a recursive omit that uses _.transform() to iterate and ignore one or more keys in an array:
const omitRecursive = (keys, obj) => _.transform(obj, (acc, v, k) => {
// if key is view, and it and has an id value replace it with equivalent from views
if(keys.includes(k)) return;
acc[k] = _.isObject(v) ? omitRecursive(keys, v) : v;
});
const data = [{"observations":[{"possibleAnswers":[],"groupMembers":[{"possibleAnswers":[]},{"groupMembers":[{"possibleMembers":[]},{"possibleMembers":[]}]}]}]},{"observations":"Same as above"},{"observations":"Same as above"}];
const result = omitRecursive(['possibleAnswers'], data);
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
This function will remove all 'possibleAnswers' if called on your original array like removeKey(arr, 'possibleAnswers')
function removeKey(objOrArr, keyToRemove) {
if (Array.isArray(objOrArr)) {
objOrArr.forEach(o => removeKey(o, keyToRemove));
} else if (typeof objOrArr === 'object') {
delete objOrArr[keyToRemove];
Object.values(objOrArr).forEach(v => removeKey(v, keyToRemove));
}
}

array.map() is not a function reactjs

I have a function which stores data after splicing from an array.
const removedItemstax = {};
function findAndRemove1(array, property, value) {
array.forEach(function(result, index) {
if(result[property] === value) {
//Remove from array
var removedItem= array.splice(index, 1);
removedItemstax.push(removedItem);
}
});
}
When I try to get map it using below code to get distinct values const tax = removedItemstax.map(d => d.taxId) I'm getting an error that .map() is not a function.
But when I push the array removedItemstax to console I get to see all the elements stored within it.
I get the same error when I pass the array removedItemstax = {} via props after setting a state to it.
Mapping returns undefined, however pushing it directly displaying complete data assigned to the array. I am following the regular method to map.
You can try this way:
const removedItemstax = [];
function findAndRemove1(array, property, value) {
array.forEach(function(result, index) {
if(result[property] === value) {
//Remove from array
var removedItem = array.splice(index, 1);
removedItemstax.push(removedItem);
}
});
}
Instead removedItemstax be a object, him can to be a array
I figured out the reason for getting undefined elements when mapping. This is due to a multidimensional array being stored in attribute const removeItemstax = [].
I'm using the below command to flatten the multidimensional array into a normal array before mapping it.
Here's the syntax:
const removedItemstax1 = [].concat.apply([], removedItemstax);

How to avoid "Arrow function expect to return a value" error in Airbnb ESLint

I am running eslint and it is recommended to return a value whenever an arrow function(lambda function) is used. Well that makes sense. However, I come across a case that is hard to walk around.
Dict = {}
Instances = [/* an array of items where items is a dictionary that contains data */]
Instances.map((item) => {
Dict[item.name] = item.url;
});
My goal is to get the data from the Instances array and fill the dictionary Dict with it. I am using the array function to assign key value pair to the dictionary, but that violates the rule of the arrow function.
Is there any iteratools or functions other than map that would help me to achieve the goal, and avoid the rule violation?
Edit: This does not adhere to Airbnb's ES6 Style Guide.
My goal is to get the data from the Instances array and fill the dictionary with it.
Use .reduce
.. and just pass an empty object as the accumulator, filling it up as you iterate through your array.
const instances = [
{ name: 'foo', url: 'https://google.com' },
{ name: 'bar', url: 'https://stackoverflow.com' }
]
const result = instances.reduce((dict, item) => {
dict[item.name] = item.url
return dict
}, {})
console.log(result)
Why not .map?
Array.map always returns a new Array and is meant for mapping each array element to another format.
If your resulting data structure shouldn't be an Array, with the same length as the Array you are operating on, you should avoid using it.
Why .reduce instead of .forEach?
I use forEach only for doing "work" rather than transforming data. Transforming data is almost always achievable with just map and/or reduce.
Here's what I mean by "work":
const users = [userInstance, userInstance, userInstance]
users.forEach(user => user.sendEmail('Hello World'))
Use forEach instead of map.
The point of map is to modify each item in an array and put the modified versions in a new array.
forEach just runs a function on each item.
If you are looking for ES6 solution to fill dictionary object this could help and should pass ESLint also:-
const dict = Instances.reduce((map, obj) => (map[obj.name] = obj.url, map), {});
update
const dict = Instances.reduce((map, obj) => {
let mapClone = {};
mapClone = Object.assign({}, map);
mapClone[obj.name] = obj.url;
return mapClone;
}, {});

Categories

Resources