I have a 2 nested object array, I would like to update the first array's nested array value with the second array nested array values. I had done a brute force approach but I would like to improve my logic.
The first array is
[{
"name": "data",
"values": [{
"cid": 1,
"ccount": 0
},
{
"cid": 2,
"ccount": 0
},
{
"cid": 3,
"ccount": 0
}
]
},
{
"name": "data1",
"values": [{
"cid": 1,
"ccount": 0
},
{
"cid": 2,
"ccount": 0
},
{
"cid": 3,
"ccount": 0
}
]
}
]
and the second array looks like
[{
"fName": "End",
"version": 1,
"cValues": [{
"id": 1,
"count": 2
},
{
"id": 2,
"count": 3
},
{
"id": 3,
"count": 4
}
]
},
{
"fName": "Start",
"version": 2,
"cValues": [{
"id": 1,
"count": 2
},
{
"id": 2,
"count": 12
},
{
"id": 3,
"count": 22
}
]
}
]
I would like to update the count of nested array values inside the first array based on the id of the second nested array values.
I had done a brute force approach, my code is
for (let i = 0; i < (arr1.length && arr2.length); i++) {
arr1[i].values[i].sort(this.sortByProperty("cid"));
for (let j = 0; j < (arr1[i].values[i].length && arr2[i].cValues.length); j++) {
if (arr1[i].values[j].cid == arr2[i].cValues[j].id) {
arr1[i].values[j].cCount = arr2[i].cValues[j].count;
}
}
}
sortByProperty(property) {
return function (a, b) {
if (a[property] > b[property])
return 1;
else if (a[property] < b[property])
return -1;
return 0;
}
}
Can anyone help me to improve my code logic?
Related
I have a quite complex json response which I have to combine, but im totally stuck. I didnt find a smart and effective way yet to detect all votedpositive matches of all users.
participants = {
"data": [
{
"userId": 2,
"votedPositive": [
{
"userId": 1
}
]
},
{
"userId": 3,
"votedPositive": [
{
"userId": 5
}
]
},
{
"userId": 4,
"votedPositive": []
},
{
"userId": 5,
"votedPositive": [
{
"userId": 2,
},
{
"userId": 3
}
]
},
{
"userId": 6,
"votedPositive": []
},
{
"userId": 7,
"votedPositive": []
},
{
"userId": 8,
"votedPositive": []
},
{
"userId": 9,
"votedPositive": []
},
{
"userId": 10,
"votedPositive": []
},
{
"userId": 11,
"votedPositive": []
},
{
"userId": 12,
"votedPositive": []
},
{
"userId": 1,
"votedPositive": [
{
"userId": 2
}
]
}
]
}
The output im expecting is a list or array with all the matching pairs. in the above example I would expect to get the information that userId 2 who voted userId 1 has a match because UserId 1 voted userId 2. Same goes for userId 3 and userId 5.
EDIT: This is what I have so far:
var participantsList = [];
for (var index = 0; index < participants.length; index++) {
for (var i = 0; i < participants[index]["votedPositive"].length; i++) {
participantsList.push([participants[index]["userId"], participants[index]["votedPositive"][i]["userId"]])
}
}
for (var index = 0; index < participantsList.length; index++) {
participantsList[index].sort(function (a, b) {
return a - b;
});
}
I created a list where im iterating based on the length of all the user ids and im pushing the userid and the voted id. After that I sorted the list so I can see duplicates now. Im not sure if it is working until here. The next step would be to filter out all duplicate combinations in another list, thats where im stuck right now.
The result I have right now is this:
[ [ 1, 2 ], [ 3, 5 ], [ 2, 5 ], [ 3, 5 ], [ 1, 2 ] ]
Create an object whose keys are the voters and values are a set of the users they voted for. Then you can go through this and find the pairs that voted for each other.
participants = {
"data": [{
"userId": 2,
"votedPositive": [{
"userId": 1
}]
},
{
"userId": 3,
"votedPositive": [{
"userId": 5
}]
},
{
"userId": 4,
"votedPositive": []
},
{
"userId": 5,
"votedPositive": [{
"userId": 2,
},
{
"userId": 3
}
]
},
{
"userId": 6,
"votedPositive": []
},
{
"userId": 7,
"votedPositive": []
},
{
"userId": 8,
"votedPositive": []
},
{
"userId": 9,
"votedPositive": []
},
{
"userId": 10,
"votedPositive": []
},
{
"userId": 11,
"votedPositive": []
},
{
"userId": 12,
"votedPositive": []
},
{
"userId": 1,
"votedPositive": [{
"userId": 2
}]
}
]
}
const votedFor = new Map();
participants.data.forEach(({
userId,
votedPositive
}) => {
if (!votedPositive.length) {
return;
}
if (!votedFor[userId]) {
votedFor.set(userId, new Set());
}
votedPositive.forEach(({
userId: target
}) =>
votedFor.get(userId).add(target)
);
});
const result = [];
votedFor.forEach((votees, voter) =>
votees.forEach(votee => {
if (votedFor.get(votee) && votedFor.get(votee).has(voter)) {
result.push([voter, votee]);
}
})
);
console.log(result);
I have an JSON file with data inside of an user
[
{
"_id": "62bd5fba34a8f1c90303055c",
"index": 0,
"email": "mcdonaldholden#xerex.com",
"nameList": [
{
"id": 0,
"name": "Wendi Mooney"
},
{
"id": 2,
"name": "Holloway Whitehead"
}
]
},
{
"_id": "62bd5fbac3e5a4fca5e85e81",
"index": 1,
"nameList": [
{
"id": 0,
"name": "Janine Barrett"
},
{
"id": 1,
"name": "Odonnell Savage"
},
{
"id": 2,
"name": "Patty Owen"
}
]
},
{
"_id": "62bd5fbaf8f417d849c135db",
"index": 2,
"email": "pattyowen#xerex.com",
"nameList": [
{
"id": 0,
"name": "Earline Goff"
},
{
"id": 1,
"name": "Glenna Lawrence"
},
{
"id": 7,
"name": "Bettye Sawyer"
}
]
I had to sort every user by : if user has more than two names
if user ids are consecutive
and if user ids are numbers
I managed to sort user by more than two names and if ids are consecutive
userData.filter(({nameList}) =>
nameList.length > 2 &&
!nameList.some(({id}, index, array) => index && array[index - 1].id !== id - 1)
);
In the case that an object has an id as number I should not return the objects. How can I implement that in my code?
The output is expected to be all the arrays that meet the filter, and some() criteria. Which is if objects has more than 2 names, its ids are consecutive and the ids should be a number.
If you want to check if the id is of type number:
(typeof id == "number")
To check if can be cast to a number
(id == parseInt(id, 10))
The complete code then (you were close):
var userData = get_data();
userData = userData.filter(function(item) {
return item.nameList.length > 2 &&
item.nameList.every(function(item, index, arr) {
return parseInt(item.id) == item.id && (index == 0 || item.id - arr[index - 1].id == 1)
})
})
console.log(userData);
function get_data() {
return [{
"_id": "62bd5fba34a8f1c90303055c",
"index": 0,
"email": "mcdonaldholden#xerex.com",
"nameList": [{
"id": 0,
"name": "Wendi Mooney"
},
{
"id": 2,
"name": "Holloway Whitehead"
}
]
},
{
"_id": "62bd5fbac3e5a4fca5e85e81",
"index": 1,
"nameList": [{
"id": 0,
"name": "Janine Barrett"
},
{
"id": 1,
"name": "Odonnell Savage"
},
{
"id": 2,
"name": "Patty Owen"
}
]
},
{
"_id": "62bd5fbaf8f417d849c135db",
"index": 2,
"email": "pattyowen#xerex.com",
"nameList": [{
"id": 0,
"name": "Earline Goff"
},
{
"id": 1,
"name": "Glenna Lawrence"
},
{
"id": 7,
"name": "Bettye Sawyer"
}
]
}
];
}
.as-console-wrapper {
max-height: 100% !important
}
I have a JSON file with data inside.
I have to filter the data by : if user has more than two names, and if user ids are consecutive.
The JSON file :
[
{
"_id": "62bd5fba34a8f1c90303055c",
"index": 0,
"email": "mcdonaldholden#xerex.com",
"nameList": [
{
"id": 0,
"name": "Wendi Mooney"
},
{
"id": 2,
"name": "Holloway Whitehead"
}
]
},
{
"_id": "62bd5fbac3e5a4fca5e85e81",
"index": 1,
"nameList": [
{
"id": 0,
"name": "Janine Barrett"
},
{
"id": 1,
"name": "Odonnell Savage"
},
{
"id": 2,
"name": "Patty Owen"
}
]
}, ...
I have managed to find an a solution to filter if the users have more than two names : userData.filter((names,i) => { return names?.nameList?.filter(names => { return names.name;}).length > 2 ; })
But I cant seem to grasp myself around the concept of filtering the consecutive ids.
Also I was advised to not use any for loops at all. Only ES6 array loops like map, forEach and filter.
Here's a solution that uses every() to compare the ID of every element with the previous ID:
const result = data.filter(({nameList}) =>
nameList.length > 2 &&
nameList.every(({id}, i, a) => !i || id === a[i - 1].id + 1)
);
Complete snippet:
const data = [{
"_id": "62bd5fba34a8f1c90303055c",
"index": 0,
"email": "mcdonaldholden#xerex.com",
"nameList": [{
"id": 0,
"name": "Wendi Mooney"
}, {
"id": 2,
"name": "Holloway Whitehead"
}]
}, {
"_id": "62bd5fbac3e5a4fca5e85e81",
"index": 1,
"nameList": [{
"id": 0,
"name": "Janine Barrett"
}, {
"id": 1,
"name": "Odonnell Savage"
}, {
"id": 2,
"name": "Patty Owen"
}]
}];
const result = data.filter(({nameList}) =>
nameList.length > 2 &&
nameList.every(({id}, i, a) => !i || id === a[i - 1].id + 1)
);
console.log(result);
I have array of arrays that contains obj, I should only take arrays that contain an obj with a specific key.
I tried to use a double filter but it doesn't work.
Can you give me some advice?
let result = [
[
{
"id": 1
},
{
"id": 2
}
],
[
{
"id": 3
},
{
"id": 4
},
{
"id": 5,
"type": {
"id": 1555
}
}
],
[
{
"id": 6,
"type": {
"id": 5456
}
}
]
];
const c = result.filter(array => array.filter(a => a.hasOwnProperty('type') === true));
console.log(c);
Result:
[
[
{
"id": 3
},
{
"id": 4
},
{
"id": 5,
"type": {
"id": 1555
}
}
],
[
{
"id": 6,
"type": {
"id": 5456
}
}
]
]
The filter in your filter function is wrong because you don't want to return a new collection, you want to return a boolean expression. Array.some() helps and checks if any item in that subarray has this property.
let result = [
[{
"id": 1
},
{
"id": 2
}
],
[{
"id": 3
},
{
"id": 4
},
{
"id": 5,
"type": {
"id": 1555
}
}
],
[{
"id": 6,
"type": {
"id": 5456
}
}]
];
const validArrays = result.filter(subArray => subArray.some(item => item.hasOwnProperty('type')));
console.log(validArrays);
You'll have to check whether the length of the return value from the inner array is > 0. Only if the length of the return value from the inner filter is > 0 the outer filter returns true and store it into validArrays.
let result = [[{"id":1},{"id":2}],[{"id":3},{"id":4},{"id":5,"type":{"id":1555}}],[{"id":6,"type":{"id":5456}}]];
const validArrays = result.filter(subarray => subarray.filter(item => item.hasOwnProperty('type') === true).length > 0);
console.log(validArrays);
I want a method that goes through a posts array, and returns a new array with only the elements that match a certain value of the userId property.
For example:
let postsArr = [
{
"userId": 1,
"id": 1
},
{
"userId": 1,
"id": 2
},
{
"userId": 2,
"id": 3
},
{
"userId": 2,
"id": 4
},
{
"userId": 3,
"id": 5
}
]
Say I want to return only the items with userId: 2.
(Something like...)
let filteredArr = postsArr.method( post => post.userId === 2)
Which would (ideally) return:
[
{
"userId": 2,
"id": 3
},
{
"userId": 2,
"id": 4
}
]
I'm sure it would be something like .map() or .filter(), but I can quite get my head round how to do it, or what the best method is in this case.
Any help appreciated.
Your pretty much there to be honest..
let postsArr = [
{
"userId": 1,
"id": 1
},
{
"userId": 1,
"id": 2
},
{
"userId": 2,
"id": 3
},
{
"userId": 2,
"id": 4
},
{
"userId": 3,
"id": 5
}
];
var farray = postsArr.filter((a) => a.userId === 2);
console.log(farray);
In ES5. We used to do this.
var newarray = postsArr.filter(function(obj){
return obj.userId === 2
})