Hi lets say I have a JSON string which represent a record in a grid containing 3 columns Id, Name, Status. I'm currently writing some JavaScript logic where you can filter the rows of data by typing some text in the text box. The filter will be applied to data in all columns. So if I type "James" Record 1 below will be returned an if I type None Record 1 and 2 will be returned. The problem is if I type Id, Name, or Status which is not the data but the attribute names, all records are always returned.
Record 1
{
Id: 1,
Name: "James",
Status: "None"
}
Record 2
{
Id: 2,
Name: "Paul",
Status: "None"
}
How can I modify a JSON string so that
{ Id: 2, Name: "Paul", Status: "None"}
will become
{ 2, "Paul", "None"}
Your question is a bit unclear (and I'm afraid Matthias' edit made that matter worse).
{ Id: 1, Name: "James", Status: "None" } is not a valid JSON string, but it is a valid Javascript object. JSON strings need to have their values within quotes.
If you are indeed dealing with a JSON string, with quoted properties, and you simply want the output you've requested, you could do something like this:
var person = '{ "Id": 1, "Name": "James", "Status": "None" }';
person = person.replace(/\s*"[^"]+"\s*:/g,"");
// > person = '{ 1, "James", "None" }'
If you are dealing with a Javascript object, a simple way of getting the values without the property names would be to do something like this:
var person = { Id: 1, Name: "James", Status: "None" };
person = Object.keys(person).map(function(k) { return person[k] }).join(',');
// > person = '1,James,None'
Both options will give you a string that you could search for just the values you're interested in. In the latter scenario, you'd need to add some formatting to turn the outcome into exactly what you have requested, but then given the question I'm assuming presentation is not a big deal.
However, if at all possible, I think your code would much more closely match your intentions if you instead modified the search algorithm to inspect values and not entire objects. You haven't shown us any of the code doing the searching, though, so I can't really add suggestions for that at this point.
Related
So I have a series of 4 JSON objects with nested data inside each of them. Each of these objects are stored in an array called classes. Here is an example of how one of the class objects is formatted:
let class_A = {
professor: "Joey Smith",
numberStudents: 25,
courseCode: "COMS 2360",
seating: {
"FirstRow": {
0: {
firstName: "Sarah",
collegeMajor: "English",
},
1: {
firstName: "Bob",
collegeMajor: "Computer Engineering",
},
2: {
firstName: "Dylan",
collegeMajor: "Mathematics",
}
},
"SecondRow": {
3: {
firstName: "Molly",
collegeMajor: "Music"
}
}
}
};
I'm struggling to figure out how to access the very last fields within each class object (firstName and collegeMajor). The furthest I was able to get was the indexes beneath each row number.
let classes = [class_A, class_B, class_C, class_D];
let classesAvailable = document.getElementById('classes');
let class = classes[classesAvailable.value];
for(rowNum in class.seating){
for(index in class.seating[rowNum]){
console.log(index);
//console.log(class.seating[rowNum[index]].firstName);
}
}
So in this example, console.log(index) prints out:
0
1
2
3
but I'm unable to print the first name and college major of each student in each row. I was trying to follow a similar logic and do console.log(class.seating[rowNum[index]].firstName) but I get the error:
Cannot read properties of undefined (reading 'firstName')
Was wondering if anyone knows what's wrong with my logic here?
console.log(class.seating[rowNum][index])
I have array that contains plenty of data. Format is always like that:
1:
UserName: "John Smith"
Priority: "2"
Time Occured: "02/09/2019 11:20:23"
Time Ended: "02/09/2019 11:20:23"
2:
UserName: "Tom Bill"
Priority: "4"
Time Occured: "01/08/2019 13:20:23"
Time Ended: "04/08/2019 15:20:23"
3:
UserName: "John Smith"
Priority: "2"
Time Occured: "06/08/2019 13:20:23"
Time Ended: "09/09/2019 15:20:23"
...
Of course there is more stuff, but just to give you idea of structure.
Array contains entries that might be under the same user name. As user can have multiple entries
What I want to do, is sort and modify it to the way I can use it on data table. I am not sure what approach might be the best or what is possible.
I was thinking that I need to modify array do some math in meantime. So in Data table I can present that John Smith, got 8 entries, two of them are sev 4 etc etc. Tom Bill got 4 entries etc. Basically I won't use original data as I need to modify some parts of it, for Example I am not interested in date itself, but if it was in the past or in the future, already got scripts for that, yet I need to do it for every single user.
A structure something like this seems to be sufficient for your requirement:
data = {
'John Smith' : [{ Priority : 1, .... }, { ...2nd instance }],
'John Doe' : [{...1st instance of John Doe}],
}
Basically an object that has the names for keys, and each key has an array of entries of data.
Whenever you wish to add more entries to John Smith, you get access to the array directly by using data['John Smith']
EDIT
To convert the data to this format.
data = [
{
'UserName': "John Smith",
'Priority': "2",
'Time Occured': "02/09/2019 11:20:23",
'Time Ended': "02/09/2019 11:20:23",
},
{
'UserName': "Tom Bill",
'Priority': "4",
'Time Occured': "01/08/2019 13:20:23",
'Time Ended': "04/08/2019 15:20:23",
},
{
'UserName': "John Smith",
'Priority': "2",
'Time Occured': "06/08/2019 13:20:23",
'Time Ended': "09/09/2019 15:20:23",
}
]
convertData = (data) =>{
let newData = {}
for(let i = 0; i<data.length; i++){
// console.log(data[i])
let name = data[i]['UserName']
tempData = {
'Priority' : data[i]['Priority'],
'Time Occured' : data[i]['Time Occured'],
//Add more properties here
}
if (newData[name]==null){
newData[name] = []
}
newData[name] = [...newData[name], tempData]
}
console.log(newData)
}
convertData(data)
Look at this codepen.
https://codepen.io/nabeelmehmood/pen/jONGQmX
The Issue:
I'm attempting to build a simple search tool. It returns a search query by matching an id to another item with the same id. Without going into the complexities, the issue I'm having is that when my data was organized previously, the map function from javascript returned all the results perfectly. However, now that my data is structured a bit differently (a collection, I think?) ....the ids don't appear to be lining up which causes the wrong search results to show.
The function in question:
const options = this.props.itemIds.map((id) => (
<Option key={this.props.itemSearchList[id].id}>
{this.props.itemSearchList[id].name}
</Option>
));
When the data was structured like this it worked as expected:
Example of previous structure:
const items = [
{
id: 0,
name: "name 0",
tags: ['#sports', '#outdoor', '#clothing'],
},
{
id: 1,
name: "name 1",
tags: ['#sports', '#outdoor', '#clothing'],
},
{
id: 2,
name: "Name 2",
tags: ['#sports', '#outdoor', '#clothing'],
},
Now that the data is a ?collection...the map function doesn't work as anticipated and it returns improper results or none at all: I've been able to use the lodash Map function on this structure successfully in the past.
Here's a screenshot of the new data:
I believe a representative way to write out the example would be:
const newItems = [
0: {
id: 0,
name: "name here",
},
1: {
id: 1,
name: "name here",
},
]
Any recommendations for making this work or need more info? Perhaps I'm misunderstanding the issue entirely, but I believe it has to do with data structure and the map function from JS. I can see results returning, but the id's are not lining up appropriately anymore.
Here's a visual representation of the misalignment. The orange is the search input and it pulling the right result. The green is the misalignment of what it's actually showing because of the data structure and mapping (I assume).
The issue is you were using index and lining that up with id as a sort of pseudo-key which is...beyond fragile. What you should be doing is keying by id (meaing itemsshould be an object) and then having a seperate array that stores the order you want. So items would be an object keyed by id:
const items = {
1: {
id: 1,
name: "name 1",
tags: ['#sports', '#outdoor', '#clothing'],
},
2: {
id: 2,
name: "name 2",
tags: ['#sports', '#outdoor', '#clothing'],
},
9: {
id: 9,
name: "Name 9",
tags: ['#sports', '#outdoor', '#clothing'],
},
};
And then itemIds (which it appears you already have) is an array with the correct order:
const itemIds = [1,9,2];
And then they can be accessed in the right order by looping over that array, and getting the element by said key:
itemIds.map((id) => {
const item = items[id];
// do something with the item
}
Take a look at how Redux recommends normalizing state shape.
https://redux.js.org/recipes/structuring-reducers/normalizing-state-shape
What you call "collections" and "maps" are actually arrays. Now one of the arrays has the objects exactly at the position in the array that matches the id:
items[5].id === 5
Now through sorting /mutating / whatever you change the order so that the element at a certain position doesnt have that as an id:
newItems[5].id // 7 :(
That means that you cannot access the item that easy anymore, you now either have to sort the array again to bring it into order, or you search for an object with the id:
newItems.find(item => item.id === 5) // { id: 5, ... }
Or you switch over to some unsorted collections like a real Map:
const itemsMap = new Map(newItems.map(item => ([item.id, item])));
So you can get a certain item with its id as:
itemsMap.get(5) // { id: 5, ... }
... but the whole thing doesnt have to do with Array.prototype.map at all.
Here was my simple solution:
const options = [];
this.props.itemList.forEach((item) => {
if (this.props.searchResults.includes(item.id)) {
options.push(<Option key={item.id}>{item.name}</Option>);
}
});
Let me know what you think (to the group that tried to help!)
I have an object:
{
id: 16,
defs: {
name: "Depot (Float)", field: "Depot"
}
}
And an array (which can have more than one object in it but for the purposes of this only has one):
[
{
Percentage Monthly Potential: 1,
Area Manager: "Ashar",
Business Unit: "Retail",
Cust no: 68345,
Depot Name: "Leicester",
Group Number: "",
Depot: 14,
Target: 46100
}
]
What I need to do is take the field value from the object and use it to find the key that it matches in the second object and retrieve the value of it, so in this case I should be getting 14.
Any help with this would be much appreciated.
Thanks for your time.
If you are using ES6, you can try this:
const field = lookupObject.defs.field;
const matches = array.map(arrayItem => {
return {
field,
value: arrayItem[field]
}
});
The matches array will contain the data you are interested in.
I am having a bit of trouble here. So I want to show a user's profile. The user belongs to groups. The logged in user can see details of any groups they have in common. Here is some example data
{
_id: "1234",
battletag: "Fake#1234",
guilds: [{
name: "Lok'Narosh!",
rank: 4,
roles: ['casual']
}, {
name: "Warlords of Draenor",
rank: 2,
roles: ['PvP', 'raider']
}, {
name: "Lok'Tar Ogar!",
rank: 3,
roles: ['raider']
}],
}
I can get the current user's groups and reduce it to ['Lok'Narosh!', 'Warlords of Draenor'], meaning that Lok'tar Ogar should be omitted from the results.
The main problem I am coming across is that most operations I know only return the first result. For example, with $elemMatch:
The $elemMatch operator limits the contents of an field from the query results to contain only the first element matching the $elemMatch condition.
Is there a way that I can filter this list to contain all matching elements against a list of elements?
You can use aggregate:
$unwind operator to deconstruct 'guilds' field.
Apply criteria with $match
Reconstruct array.
db.getCollection('yourColl').aggregate({$unwind:"$guilds"},{$match:{"guilds.rank":{$gte:2.0}}},{$group:{ "_id":"$_id", "battletag":{$first:"$battletag"},"guilds":{$addToSet:"$guilds"}}})