How to alter some values of an array in react - javascript

I am working on react project. I have an array which is not a state variable but a constant. The array contains undefined values as its element. I want to make undefined values as empty array. The array finally should contain values without undefined values. Can anyone help to solve this issue?
if array is [undefined, 1,2,[] ], i need to convert it to [[], 1,2,[] ]
array.forEach(dataSet =>
(dataSet.dataPoint = (dataSet.dataPoint === undefined) ? [] : dataSet.dataPoint)
);

you can map your array into another array:
const array2 = array1.map(item => {
return typeof item === 'undefined'
? []
: item
})
https://codepen.io/giannidk/pen/PoYQvBM?editors=0011

1) Use map as you are trying to return array as forEach just iterates over the array.
const array = [undefined, 1,2,[] ]
let newArr = array.map((dataSet) => {
return dataSet = (dataSet === undefined) ? [] : dataSet
})
console.log(newArr) // [[], 1, 2,[]]

You could map over the array and return the value of what you'd like in the new array:
array = array.map(dataSet =>
(dataSet.dataPoint = (dataSet.dataPoint === undefined) ? [] : dataSet.dataPoint)
);
let array = [{}, { dataPoint: 1 }, {}, { dataPoint: 2 }];
array = array.map(dataSet =>
(dataSet.dataPoint = (dataSet.dataPoint === undefined) ? [] : dataSet.dataPoint)
);
console.log(array)
An approach to mutate the original array (rather than reassign / create a new array):
const array = [{}, {
dataPoint: 1
}, {}, {
dataPoint: 2
}];
array.forEach((dataSet, index) => {
array[index] = dataSet.dataPoint === undefined ? [] : dataSet.dataPoint
});
console.log(array)

Related

Filter an array of objects, by keys in filter object

i'm new here, i have problem that i can not solve.
I have 2 different arrays:
The first array - contains ratings of users with their ID name
[
{"handle":"frontend1", "_redis":"3", "_nodejs":"5", "_mysql":"2", "_python":"3", "_mongo":"4"},
{"handle":"frontend3", "_php":"4", "_mysql":"4", "_oracle":"4", "_ruby":"3", "_mongo":"5", "_python":"5"},
{"handle":"frontend4", "_java":"5", "_ruby":"5", "_mysql":"5", "_mongo":"5"}
]
The second set - contains the ratings, which I want to return to each user.
If there is a rating that is not in the second set, I will not return it
In the second set, values do not matter, only keys
[
"_assembler",
"_css",
"_python",
"_php"
]
I want to return to the first set, the handle, and all the rankings that exist in the second set.
[
{"handle":"frontend1", "_python":"3" },
{"handle":"frontend3", "_php":"4", "_python":"5" },
{"handle":"frontend4"}
]
this is what i try to do.
keys = [
"_assembler",
"_css",
"_python",
"_php"
]
source = [
{"handle":"frontend1", "_redis":"3", "_nodejs":"5", "_mysql":"2", "_python":"3", "_mongo":"4"},
{"handle":"frontend3", "_php":"4", "_mysql":"4", "_oracle":"4", "_ruby":"3", "_mongo":"5", "_python":"5"},
{"handle":"frontend4", "_java":"5", "_ruby":"5", "_mysql":"5", "_mongo":"5"}
];
result = [];
tmp = {};
source.forEach((item) => {
Object.keys(item).map(({key,value}) =>
{
if(key == "handle")
{
tmp[key]=value;
}
if(keys.includes(key))
{
tmp[key]=value;
}
})
result.push(...tmp);
tmp = {};
});
You can do this with a map utilizing a couple of other array methods such as filter, and Object methods.
const keys = [
"_assembler",
"_css",
"_python",
"_php"
]
const source = [
{"handle":"frontend1", "_redis":"3", "_nodejs":"5", "_mysql":"2", "_python":"3", "_mongo":"4"},
{"handle":"frontend3", "_php":"4", "_mysql":"4", "_oracle":"4", "_ruby":"3", "_mongo":"5", "_python":"5"},
{"handle":"frontend4", "_java":"5", "_ruby":"5", "_mysql":"5", "_mongo":"5"}
];
const result = source.map( s => ({
handle: s.handle,
...Object.fromEntries(Object.entries(s).filter(x => x[0] != "handle" && keys.includes(x[0])))
}));
console.log(result);

Get all Indexes of Objects in Array - from Array in Object

i´m struggling with a Array in a Object stored in a Array with Objects from which I want return all Indicies.
Function to generate Object looks like this:
const addArray = function(a, b) {
const object = {
name: a,
rooms: b
};
testArray.push(object);
};
What I want to achieve is to cycle through the "testArray" and return every Index from the Object where the Array Rooms contains "Office" for example.
I´ve already tried to use a function like this but I don´t seem to be able to get the right Syntax for the Array in the Object:
function getAllIndexes(arr, val) {
var indexes = [], i = -1;
while ((i = arr.rooms.indexOf(val, i+1)) != -1){
indexes.push(i);
}
return indexes;
};
Thanks in advance!
Edit:
Additional Informations to Data:
A Object with data filled would look like this:
const device = {
name: "TV",
rooms: ["Living Room", "Bedroom"]
};
After generating Objects like this I push them to an array witch only contains this objects (see function addArray)
You can use Array.flatMap() to map each value of the array at matches val to it's index, and the rest to empty array, which will be removed by the flatMap:
const getAllIndexes =(arr, val) => arr.flatMap((v, i) => v === val ? i : [])
const arr = [1, 2, 3, 1, 2, 1, 1, 2]
const result = getAllIndexes(arr, 1)
console.log(result)
Using your array of objects, you'll need to compare a value, or check if an object meets some condition. It's better in this case to replace val with a predicate function:
const getAllIndexes =(arr, pred) => arr.flatMap((v, i) => pred(v) ? i : [])
const arr = [{ rooms: [1, 2, 3] }, { rooms: [2, 1, 1] }, { rooms: [3, 2, 2] }, { rooms: [1, 2, 1] }]
const result = getAllIndexes(arr, o => o.rooms.includes(1))
console.log(result)
Try using Array.prototype.map and Array.prototype.filter
function getAllIndexes(arr, val) {
return arr.map(i=> {
let room = i.rooms;
return room.indexOf(val);
}).filter(a=>{
a != -1;
});
};
You could destructure rooms from the device and get the index, if the wanted value is found.
const
room = 'Office',
indices = array.flatMap(({ rooms }, i) => rooms.includes(room) ? i : []);
The above code features a former solution from me with hacking Array#flatMap.

Recursively list nested object keys

i have an nested object as such:
options = {
religous: {
kosher: {
value: 'Kosher',
chosen: false
},
halal: {
value: 'Halal',
active: false
},
},
vegan: {
value: 'Vegan',
active: false
}
}
It contains nested objects of varying sizes. I would like to get an Array containing the values of any value propery. So for the above object the desired output would be:
['Kosher', 'Halal', 'Vegan']
Order doesn't really matter.
I tried to do so recursively as such:
getListOfLabels = obj => {
const lst = []
for (let key in obj) {
if (obj[key].value) lst.push(obj[key].value)
else return getListOfLabels(obj[key])
}
return lst
}
but I keep getting a RangeError: Maximum call stack size exceeded error.
Any suggestions?
The for...in loop assigns the key. To get the value use obj[key]. If the key is value add to lst, if it's an object, call getListOfLabels on it, and spread the results into lst.push():
const options = {"religous":{"kosher":{"value":"Kosher","chosen":false},"halal":{"value":"Halal","active":false}},"vegan":{"value":"Vegan","active":false}}
const getListOfLabels = obj => {
const lst = []
for (let key in obj) {
const val = obj[key] // get the value
if (key === 'value') lst.push(val) // if the key name is "value" push to lst
else if(typeof val === 'object') lst.push(...getListOfLabels(val)) // if type of value is object, iterate it with getListOfLabels and push the results into lst
}
return lst
}
const result = getListOfLabels(options)
console.log(result)
You could take a recursive approach and check if the object contains a value key.
function getValues(object, key) {
if (key in object) return [object[key]];
return Object.values(object).reduce((r, v) => {
if (v && typeof v === 'object') r.push(...getValues(v, key));
return r;
}, []);
}
var options = { religous: { kosher: { value: 'Kosher', chosen: false }, halal: { value: 'Halal', active: false } }, vegan: { value: 'Vegan', active: false } };
console.log(getValues(options, 'value'));
Here's a succinct approach using reduce :-D
const getValues = options => Object.values(options)
.reduce((acc, optionObj) => (
optionObj.value ? [ ...acc, optionObj.value ] : [
...acc,
...Object.values(optionObj).reduce((arr, { value }) => ([ ...arr, value ]), [])
]), [])

Push in an a new array and filtering redundant objects in javascript

I receive from an ajax call an array of object and some of them are the same, so i want want to push only unique objects in an another array.
receivedArray = [{name:italy, id:67},{name:italy, id:67},{name:france, id:89}]
and i want that :
myArray = [{name:italy, id:67},{name:france, id:89}]
how can i do that ?
Use reduce & findIndex method. findIndex will return the index of the object if the accumulator array already have an object where the id matches. If index is -1 which mean that accumulator array does not have that object.In that case add the array to the accumulator array
let receivedArray = [{
name: 'italy',
id: 67
}, {
name: 'italy',
id: 67
}, {
name: 'france',
id: 89
}]
let myArray = receivedArray.reduce(function(acc, curr) {
let findIndex = acc.findIndex(function(item) {
return item.id === curr.id;
})
if (findIndex === -1) {
acc.push(curr)
}
return acc;
}, [])
console.log(myArray)
You can use filter and Set to do something like this perhaps:
receivedArray = [{name:'italy', id:67},{name:'italy', id:67},{name:'france', id:89}]
mySet = new Set();
myArray = receivedArray.filter(e => {
if (mySet.has(e['id'])) {
return false;
} else {
mySet.add(e['id']);
return true;
}
})
console.log(myArray);
This can be easily solved in es6:
const receivedArray = [{name:'italy', id:67},{name:'italy', id:67},{name:'france', id:89}]
const newArr = receivedArray.filter((item, index, self) =>
index === self.findIndex((i) => (
i.id === item.id && i.name === item.name
))
)
console.log(newArr)

Pick the array by property name from another array

I have an array like that
I want to pick the array item by property name, I am using lodash for that:
const result = _.map(this.thing, _.property('groups')).filter(x => x !== undefined);
But I am getting array of arrays as result
What I need is just single selected property array.
Any idea how to achieve that?
Try this>>>
var a = [{"p1":[3,4]},{"p2":[6,7]}];
function getArr(arr,key){
var res = [];
for(var v of arr){
if(v[key]!=undefined){
res = v[key];break;
}
};
return res;
}
console.log(getArr(a,"p1"));
If you can use ES6/ES7, you can rely on Object.keys and Object.values to access to the key (that is the property name) and the value (the array you want to get):
var arr = [
{ groups: [1, 2 ] },
{ category: [1, 2, 3 ] },
{ subCategory: [1, 2, 3, 4 ] }
];
function pickArray(propertyName) {
var element = arr.find(el => Object.keys(el)[0] === propertyName)
return element ? Object.values(element)[0] : null;
}
var res = pickArray('category');
console.log(res);
const output
= (Array.from(arr, (obj) => obj['product'], 'product')
.filter(x => typeof x !== 'undefined'))[0];
Try this:
const arr = [ {'groups': ['item1','item2']},
{'categories':['x','y']}
]
var ouptut= arr.find(item=> {
return item[Object.keys(item).find(key=>key === 'groups')]
})
console.log(ouptut)

Categories