I have an object like
let arr = [
{isManaged: true, id:1},
{isManaged: false, id:2},
{isManaged:false, id:3}
]
to get the values which are true, i do
arr.map(shift => ({
id: shift.id,
isPartnerManaged: shift.isManaged,
}))
but this will only return me the values where i true, now, I want to remove them from the array of objects. I tried to use the array.pop but i don't know what index to feed it. Any ideeas?
arr = arr.filter(shift => shift.isManaged);
You could filter the array and build new objects.
var array = [{ isManaged: true, id: 1 }, { isManaged: false, id: 2 }, { isManaged: false, id: 3 }],
result = array
.filter(({ isManaged }) => isManaged)
.map(({ isManaged: isPartnerManaged, id }) => ({ id, isPartnerManaged }));
console.log(result);
Related
I want to find a nice / elegant (maybe using lodash) way to do compare 2 different colections and on equality (according to my defenition of equal) take some value from 1 collection and another value from the other collection and map it to a new collection, like so:
const filter1 = [{
columnName : "date",
value : "12/5"
},
{
columnName : "age",
value : "12"
}]
const filter2 = [{
valueName : "age",
displayName: "Age"
},
{
valueName : "date",
displayName: "DateD"
}]
filter1.map((val) => ({
displayName: filter2.find(filter => filter.valueName === val.columnName).displayName,
value : val.value
}))
to get:
[{
displayName: "DateD",
value: "12/5"
}, {
displayName: "Age",
value: "pa"
}]
Convert the 2nd array to a Map using valueName as the rest of the object as the value. Create the new array by mapping the 1st array, getting the items from the Map using columnName and merging it with the values from the 1st array using object spread.
const fn = (arr1, arr2) => {
const arr2Map = new Map(arr2.map(({ valueName, ...rest }) => [valueName, rest]))
return arr1.map(({ columnName, ...rest }) => ({
...arr2Map.get(columnName),
...rest
}))
}
const filter1 = [{"columnName":"date","value":"12/5"},{"columnName":"age","value":"12"}]
const filter2 = [{"valueName":"age","displayName":"Age"},{"valueName":"date","displayName":"DateD"}]
const result = fn(filter1, filter2)
console.log(result)
I have the following arrays:
First array:
const dummyJSON = [
{
id: 1,
sponsor_date: '2020-08-16T22:45:03.154Z'
},
{
id: 2,
sponsor_date: '2020-09-16T22:45:03.154Z'
},
{
id: 3,
sponsor_date: '2020-09-01T22:45:03.154Z'
}
]
Second array:
const validated = [ true, false, false ]
And I wanted to get the object (dummyJSON.id) when the corresponding (validated) array item is true.
Basically, if the first item in the validate [0] array has a value of "true", then I would like to have the corresponding [0] item's id value in the dummyJSON array.
You can use Array#reduce to get array of validated ids.
It will basically loop over every element and if the index of currently iterated object corresponds to the truthy value inside validated with the very same index, the object's id will be pushed to the result.
const dummyJSON = [
{ id: 1, sponsor_date: '2020-08-16T22:45:03.154Z' },
{ id: 2, sponsor_date: '2020-09-16T22:45:03.154Z' },
{ id: 3, sponsor_date: '2020-09-01T22:45:03.154Z' }
];
const validated = [true, false, false];
const validatedIds = dummyJSON
.reduce((s, { id }, i) => (validated[i] ? s.push(id) : s, s), []);
console.log(validatedIds);
If your goal is just to get the validated items, use filter:
const valid = dummyJSON.filter((item, index) => validated[index]);
If you just want the ids, add a map call:
const valid = dummyJSON.filter((item, index) => validated[index]);
const ids = valid.map(x => x.id);
This could be done in a single line if you prefer, by chaining the map call:
const ids = dummyJSON.filter((item, index) => validated[index]).map(x => x.id);
const dummyJSON = [
{ id: 1, sponsor_date: '2020-08-16T22:45:03.154Z' },
{ id: 2, sponsor_date: '2020-09-16T22:45:03.154Z' },
{ id: 3, sponsor_date: '2020-09-01T22:45:03.154Z' }
];
const validated = [ true, false, false ];
// source objects
console.log(dummyJSON.filter((_, index) => validated[index]));
// just the ids
console.log(dummyJSON.filter((_, index) => validated[index]).map(x => x.id));
No need for reduce, filter can do that just as well and faster :
const validated = [ true, false, false ]
const dummyJSON = [
{
id: 1,
sponsor_date: '2020-08-16T22:45:03.154Z'
},
{
id: 2,
sponsor_date: '2020-09-16T22:45:03.154Z'
},
{
id: 3,
sponsor_date: '2020-09-01T22:45:03.154Z'
}
]
// To get all validated objects from dummy JSON
const validatedJSON = dummyJSON.filter((obj, index) => validated[index])
// To extract just the ID's
const validatedJSONIds = validatedJSON.map(json => json.id)
I have 2 arrays of objects. One array receives the data from the API and renders it in the application, the other receives the data from localStorage, which are data from the first and which have been changed and stored in localStorage. I want to concatenate these two arrays, but I need to remove the repeated data in order not to render the same object twice.
example of what I hope:
dado1 = [
{customer: {
purchased: false,
id: 1
}},
{customer: {
purchased: false,
id: 2
}}
]
dado2 = [
{customer: {
purchased: true,
id: 1
}}
]
dado3 = dado1.concat (dado2)
result:
dado3 = [
{customer: {
purchased: true,
id: 1
}},
{customer: {
purchased: false,
id: 2
}}
]
I am not able to compare the two arrays. I've thought of several ways, but I always fail
some thing like that ?
const dado1 =
[ { customer: { purchased: false, id: 1 } }
, { customer: { purchased: false, id: 2 } }
]
const dado2 =
[ { customer: { purchased: true, id: 1 } }
]
const dado3 = dado1.map(el=>
{
let nv = dado2.find(x=>x.customer.id === el.customer.id )
return nv? nv : el
})
console.log( dado3 )
.as-console-wrapper { max-height: 100% !important; top: 0; }
but be carrefull, this is array of object of object so prefer to use
const dado3 = dado1.map(el=>
{
let nv = dado2.find(x=>x.customer.id === el.customer.id )
return nv? JSON.parse(JSON.stringify(nv)) : JSON.parse(JSON.stringify(el))
})
if you want a real new array
You can make your customer objects unique by mapping them by the id field, and ensuring that entries from the 2nd object take precedence (this will prefer local storage over api results):
let mergeCustomerData = (arr1, arr2) => {
// Both arrays are converted to maps, where the `item.customer.id` property determines the key
[ arr1, arr2 ] = [ arr1, arr2 ].map(arr => new Map(arr.map(v => [ v.customer.id, v ])));
// Merge these Maps into one (preference determined by the order of `arr1` and `arr2`)
let merged = new Map([ ...arr1, ...arr2 ]);
// Return the merged values, converted back to an Array
return [ ...merged ].map(([ id, v ]) => v);
};
let dado1 = [
{ customer: { purchased: false, id: 1 } },
{ customer: { purchased: false, id: 2 } }
];
let dado2 = [
{ customer: { purchased: true, id: 1 } }
];
console.log(mergeCustomerData(dado1, dado2));
Collect the ids from the second array. Take as result the second array plus all elements from the first array which have a id that is not in the stored ids.
dado1 = [
{customer: { purchased: false, id: 1 }},
{customer: { purchased: false, id: 2 }}
];
dado2 = [
{customer: { purchased: true, id: 1 }},
{customer: { purchased: true, id: 5 }}
];
function concatDado( dado1, dado2) {
let result = dado2;
let ids = [];
dado2.forEach(element => ids.push(element.customer.id));
dado1.forEach(element => {
id = element.customer.id;
if ( ids.indexOf(id) == -1 )
result.push(element);
});
return result;
}
console.log( concatDado( dado1, dado2));
I havve two different arrays with different property names like below
arrayA = [
{ id: 20, name: 'Jason' },
{ id: 15, name: 'Harry' },
{ id: 5, name: 'Clara' },
{ id: 9, name: 'Melonie' }
]
arrayB = [
{ courseID: 12, studentID: 20 },
{ courseID: 12, studentID: 15 }
]
I want to compare these two different arrays and remove unmatched ids from arrayA. For comparison, id field of arrayA and studentID field of arrayB matters. if these fileds aren't equal to each other, they should be removed from arrayA.
Expected is below
arrayA = [{id: 20, name: 'Jason' }, { id: 15, name: 'Harry' }]
Here is what I tried below but didn't work. Gave me empty array.
filteredElements = this.arrayA.map(e => e.id).filter(
val => this.arrayB.indexOf(val.studentID) !== -1
);
You can do that in following steps:
Use map() on arrayB and create array of courseID.
Then create a Set() from that Array
Then use filter() arrayA and check whether id of object exists in above created Set or not using Set.prototype.has()
const arrayA = [{id:20,name:'Jason'},{id:15,name:'Harry'},{id:5,name:'Clara'},{id:9,name:'Melonie'}]
const arrayB =[{courseID:12,studentID:20},{courseID:12,studentID:15}];
const ids = new Set(arrayB.map(x => x.studentID));
const res = arrayA.filter(x => ids.has(x.id));
console.log(res);
let arrayA = [{id: 20,name: 'Jason'},{id: 15,name: 'Harry'},{id: 5,name: 'Clara'},{id: 9,name: 'Melonie'}]
let arrayB = [{courseID: 12,studentID: 20},{courseID: 12,studentID: 15}];
let filtered=arrayA.filter(obj =>{ if(arrayB.find(course => course.studentID == obj.id))return true;return false;
});
console.log(filtered);
Try this:
var studentIds = arrayB.map(course => course.studentID);
var result = arrayA.filter(student => studentIds.includes(student.id));
The variable result contains your result.
Create a dictionary from courseMembers, keyed on studentID, to enable O(1) lookup.
Filter students according to the dictionary.
const students = [{id:20,name:'Jason'},{id:15,name:'Harry'},{id:5,name:'Clara'},{id:9,name:'Melonie'}]
const courseMembers = [{courseID:12,studentID:20},{courseID:12,studentID:15}]
function withCourses(students, courseMembers) {
const map = courseMembers.reduce((acc, {studentID}) =>
(acc[studentID] = true, acc), {})
return students.filter(({id}) => map[id])
}
const result = withCourses(students, courseMembers)
console.log(result) // [{ id:20, name:"Jason" },{ id:15, name:"Harry" }]
I have an array of objects like below;
const arr1 = [
{"name": "System.Level" },
{"name": "System.Status" },
{"name": "System.Status:*" },
{"name": "System.Status:Rejected" },
{"name": "System.Status:Updated" }
]
I am trying to split name property and create an object. At the end I would like to create an object like;
{
"System.Level": true,
"System.Status": {
"*": true,
"Rejected": true,
"Updated": true
}
}
What I have done so far;
transform(element){
const transformed = element.split(/:/).reduce((previousValue, currentValue) => {
previousValue[currentValue] = true;
}, {});
console.log(transofrmed);
}
const transofrmed = arr1.foreEach(element => this.transform(element));
The output is;
{System.Level: true}
{System.Status: true}
{System.Status: true, *: true}
{System.Status: true, Rejected: true}
{System.Status: true, Updated: true}
It is close what I want to do but I should merge and give a key. How can I give first value as key in reduce method? Is it possible to merge objects have same key?
You could reduce the splitted keys adn check if the last level is reached, then assign true, otherwise take an existent object or a new one.
const
array = [{ name: "System.Level" }, { name: "System.Status" }, { name: "System.Status:*" }, { name: "System.Status:Rejected" }, { name: "System.Status:Updated" }],
object = array.reduce((r, { name }) => {
var path = name.split(':');
last = path.pop();
path.reduce((o, k) => o[k] = typeof o[k] === 'object' ? o[k] : {}, r)[last] = true;
return r;
}, {});
console.log(object);
Use Array.reduce() on the list of properties. After splitting the path by :, check if there is second part. If there is a second part assign an object. Use object spread on the previous values, because undefined or true values would be ignored, while object properties would be added. If there isn't a second part, assign true as value:
const array = [{ name: "System.Level" }, { name: "System.Status" }, { name: "System.Status:*" }, { name: "System.Status:Rejected" }, { name: "System.Status:Updated" }];
const createObject = (arr) =>
arr.reduce((r, { name }) => {
const [first, second] = name.split(':');
r[first] = second ? { ...r[first], [second]: true } : true;
return r;
}, {});
console.log(createObject(array));