sort and pattern match an json - javascript

Am having a json like below,
[
{
"id": "1",
"freq": "1",
"value": "Tiruchengode",
"label": "Tiruchengode"
},
{
"id": "2",
"freq": "1",
"value": "Coimbatore",
"label": "Coimbatore"
},
{
"id": "3",
"freq": "1",
"value": "Erode",
"label": "Erode"
},
{
"id": "4",
"freq": "1",
"value": "Madurai",
"label": "Madurai"
},
{
"id": "5",
"freq": "1",
"value": "Salem",
"label": "Salem"
},
{
"id": "6",
"freq": "1",
"value": "Tiruchirappalli",
"label": "Tiruchirappalli"
},
{
"id": "7",
"freq": "1",
"value": "Tirunelveli",
"label": "Tirunelveli"
}
]
I need to pattern match it with label item in this json (ie), If I type tiru, then it has to result label items having tiru substrings in it.If its a single item array I know how to pattern match and sort it. Here am completely unaware that, how to pattern match using label item in the array. Is it possible to?. I need to do with Pure javascript, any help guys?

You can use the functional array methods introduced in JavaScript 1.6, specifically filter:
var search = 'tiru';
var results = obj.filter(function(item) {
var a = item.label.toUpperCase();
var b = search.toUpperCase();
return a.indexOf(b) >= 0;
});
If you wanted labels only, you can then use map to return only that property alone:
var labels = obj.filter(function(item) {
var a = item.label.toUpperCase();
var b = search.toUpperCase();
return a.indexOf(b) >= 0;
}).map(function(item) {
return item.label;
});
Essentially, filter is a method available to any Array which returns a new Array containing only those members for which the supplied function return true.

JSON.parse() will help convert the jsonString to JsonObject then just iterate the object use indexOf for pattern matching.
var jsonString = '[{"id": "1","freq": "1","value": "Tiruchengode","label": "Tiruchengode"},{"id": "2","freq": "1","value": "Coimbatore","label": "Coimbatore"},{"id": "3","freq": "1","value": "Erode","label": "Erode"},{"id": "4","freq": "1","value": "Madurai","label": "Madurai"},{"id": "5","freq": "1","value": "Salem","label": "Salem"},{"id": "6","freq": "1","value": "Tiruchirappalli","label": "Tiruchirappalli"},{"id": "7","freq": "1","value": "Tirunelveli","label": "Tirunelveli"}]';
var jsonObjects = JSON.parse(jsonString);
var pattern = "tiru";
for(var key in jsonObjects){
var label = jsonObjects[key].label.toUpperCase();
if(label.indexOf(pattern.toUpperCase()) != -1){
document.write(label+"<br/>");
}
}

Related

Getting the key in every JSON object

I am fairly new to Vue and JS but I am making API calls and getting a JSON response then sending the response to an empty array. How do I get the ID of each object in the array?
The array that the response is being pushed to is structured like this
groups: [
{
"id": "0",
"name": "a",
"price": 5
},
{
"id": "1",
"name": "b",
"price": 5
},
{
"id": "2",
"name": "c",
"price": 5
}
]
I'd like to pull the Id of each object and push the values to an empty array
for(var group in this.groups) {
if (this.groups.hasOwnProperty(0)) {
this.group = this.groups[0];
this.groupsId.push(this.innerObj);
}
}
The error I'm getting is saying Cannot read property '0' of undefined at eval
Ideally I'd like an array that has all the Ids of each object.
this.groups.hasOwnProperty(0) should be group.hasOwnProperty('id')
Use Array.prototype.map() to iterate over an array of objects and collect every ID into a new array:
const res = {
groups: [{
"id": "0",
"name": "a",
"price": 5
},
{
"id": "1",
"name": "b",
"price": 5
},
{
"id": "2",
"name": "c",
"price": 5
}
]
};
const ids = res.groups.map(obj => { // you use this.groups
if(obj.hasOwnProperty('id')) return obj.id;
});
console.log(ids)
There is the Array.map() method:
this.groupsId = this.groups.map(i => i.id);
If you already have elements in this.groupsId you can append the ids using Array.concat():
this.groupsId = this.groupsId.concat(this.groups.map(i => i.id));
You can use Array.prototype.reduce to loop and check if there's id.
const groups = [
{"name": "a","price": 5},
{"id": "1","name": "b","price": 5},
{ "id": "2","name": "c","price": 5}
];
const list = groups.reduce((groupIds, group) => group.id ? [...groupIds, group.id] : groupIds, []);
console.log(list);

check if record exists in javascript object

I have a web app which passes delimited fields to another web page. It works fine! But... I want to list the fields (Name) that don't exist in the javascript object. How can this be accomplished?
JS object:
var members = [ { "Class": "E", "Rating": "1000", "ID": "16720664", "Name": "Adeyemon, Murie", "Expires": "1000.10.10" },
{ "Class": "B", "Rating": "1735", "ID": "12537964", "Name": "Ahmed, Jamshed", "Expires": "2018.10.18" },
{ "Class": "C", "Rating": "1535", "ID": "12210580", "Name": "Attaya, James", "Expires": "2019.01.12" },
{ "Class": "F", "Rating": "0001", "ID": "16281977", "Name": "Auld, Thomas", "Expires": "1000.10.10" },
{ "Class": "B", "Rating": "1793", "ID": "10117780", "Name": "Badamo, Anthony", "Expires": "2018.09.12" }
]
JS CODE:
let dataString = "Adeyemon, Murie|Ahmed, Jamshed|Attaya, James|Badamo, Anthony|Birmingham, Gerald|";
let splitString = dataString.split("|");
for (let i = 0; i < splitString.length; i++) {
$temp = splitString[i - 1];
if ($temp > "") {
members.find(x => x.Name === $temp);
}
}
use filter
var dataString =
'Adeyemon, Murie|Ahmed, Jamshed|Attaya, James|Badamo, Anthony|Birmingham, Gerald|'
var members = [{"Class":"E","Rating":"1000","ID":"16720664","Name":"Adeyemon, Murie","Expires":"1000.10.10"},{"Class":"B","Rating":"1735","ID":"12537964","Name":"Ahmed, Jamshed","Expires":"2018.10.18"},{"Class":"C","Rating":"1535","ID":"12210580","Name":"Attaya, James","Expires":"2019.01.12"},{"Class":"F","Rating":"0001","ID":"16281977","Name":"Auld, Thomas","Expires":"1000.10.10"},{"Class":"B","Rating":"1793","ID":"10117780","Name":"Badamo, Anthony","Expires":"2018.09.12"}]
var res = dataString.split('|').filter(
name => !members.map(o => o.Name).find(n => n === name)
).filter(name=>name.trim()!=='')
console.log(res);
You can first create Name to object mapping and then search name from string in this object/map which will cost O(n) for n names.
var members = [ { "Class": "E", "Rating": "1000", "ID": "16720664", "Name": "Adeyemon, Murie", "Expires": "1000.10.10" },
{ "Class": "B", "Rating": "1735", "ID": "12537964", "Name": "Ahmed, Jamshed", "Expires": "2018.10.18" },
{ "Class": "C", "Rating": "1535", "ID": "12210580", "Name": "Attaya, James", "Expires": "2019.01.12" },
{ "Class": "F", "Rating": "0001", "ID": "16281977", "Name": "Auld, Thomas", "Expires": "1000.10.10" },
{ "Class": "B", "Rating": "1793", "ID": "10117780", "Name": "Badamo, Anthony", "Expires": "2018.09.12" }
];
var nameMap = members.reduce((prev, next) => {
prev[next.Name] = next;
return prev;
}, {});
let dataString = "Adeyemon, Murie|Ahmed, Jamshed|Attaya, James|Badamo, Anthony|Birmingham, Gerald|";
let names = dataString.split("|");
let result = names.filter(name => name && !(name in nameMap));
console.log(result);
Try reducing the members array to a Set of names. Then you can filter your splitString array using Set.prototype.has()
const members = [{"Class":"E","Rating":"1000","ID":"16720664","Name":"Adeyemon, Murie","Expires":"1000.10.10"},{"Class":"B","Rating":"1735","ID":"12537964","Name":"Ahmed, Jamshed","Expires":"2018.10.18"},{"Class":"C","Rating":"1535","ID":"12210580","Name":"Attaya, James","Expires":"2019.01.12"},{"Class":"F","Rating":"0001","ID":"16281977","Name":"Auld, Thomas","Expires":"1000.10.10"},{"Class":"B","Rating":"1793","ID":"10117780","Name":"Badamo, Anthony","Expires":"2018.09.12"}]
const dataString = "Adeyemon, Murie|Ahmed, Jamshed|Attaya, James|Badamo, Anthony|Birmingham, Gerald|";
const names = members.reduce((c, {Name}) => c.add(Name), new Set())
const missing = dataString.split('|')
.filter(name => name.trim() && !names.has(name))
.join('; ') // output from your comment on another answer
console.info(missing)
I've added in the name.trim() to filter out the empty record created by the trailing | in your dataString.
The reason for creating a Set is to avoid searching the entire members array for each name in dataString. Set.prototype.has() should be O(1)

Merging two json array object based on union and intersection

I am trying to merge two json array with objects as element. You may refer to this plunkr file for both json. I have succesfully retrieve the expected final outcome array id, but I do not know how to form back the expected json as below. I am using underscore js for this purpose.
Note: If object exist in newJson and not in currentJson, after merge, it will be inactive state by default.
I am not sure whether I am using the correct approach. This is what I have try:
var newJsonID = _.pluck(newJson, 'id');
var currentJsonID = _.pluck(currentJson, 'id');
var union = _.union(newJsonID, currentJsonID);
var intersection = _.intersection(currentJsonID, newJsonID);
var final = _.difference(union, _.difference( currentJsonID, intersection);
Expected Final Outcome:
[
{
"id": "12",
"property1Name": "1"
"status": "inactive"
},
{
"id": "11",
"property1Name": "1"
"status": "inactive"
},
{
"id": "10",
"property1Name": "1"
"status": "inactive"
},
{
"id": "9",
"property1Name": "1"
"status": "active"
}
]
A solution in plain Javascript with two loops and a hash table for lookup.
function update(newArray, currentArray) {
var hash = Object.create(null);
currentArray.forEach(function (a) {
hash[a.id] = a.status;
});
newArray.forEach(function (a) {
a.status = hash[a.id] || 'inactive';
});
}
var newJson = [{ "id": "12", "property1Name": "1" }, { "id": "11", "property1Name": "1" }, { "id": "10", "property1Name": "1" }, { "id": "9", "property1Name": "1" }],
currentJson = [{ "id": "10", "property1Name": "1", "status": "inactive" }, { "id": "9", "property1Name": "1", "status": "active" }, { "id": "8", "property1Name": "1", "status": "active" }, { "id": "7", "property1Name": "1", "status": "inactive" }];
update(newJson, currentJson);
document.write('<pre>' + JSON.stringify(newJson, 0, 4) + '</pre>');

How to check that object with same ID (or any other attribute ) exists in array of objects?

I have following array:
var array = [
{
"milestoneTemplate": {
"id": "1",
"name": "TEST1"
},
"id": "1",
"date": "1416680824",
"type": "ETA",
"note": "Note",
"color": "66FF33"
},
{
"milestoneTemplate": {
"id": "2",
"name": "Test 2"
},
"id": "2",
"date": "1416680824",
"type": "ATA",
"note": "Note 22",
"color": "66FF00"
}
];
And now i would like to check in forEach loop that object (which is passed in param of the function) is existing in array by his ID.
In case that not = do push into existing array.
arrayOfResults.forEach(function(entry) {
if(entry != existingInArrayByHisId) {
array.push(entry);
}
});
Thanks for any advice
You could create a helper function thats checks if an array contains an item with a matching property value, something like this:
function checkForMatch(array, propertyToMatch, valueToMatch){
for(var i = 0; i < array.length; i++){
if(array[i][propertyToMatch] == valueToMatch)
return true;
}
return false;
}
which you can then use like so:
arrayOfResults.forEach(function (entry) {
if (!checkForMatch(array, "id", entry.id)) {
array.push(entry);
}
});

Format Array into new Array

I have an array of objects. I would like to reformat into a new array but am not sure how to begin. I have jQuery and Underscore available.
Here is my original array:
var myArray = [
{
"name": "Product",
"value": "Car"
},
{
"name": "Product",
"value": "Boat"
},
{
"name": "Product",
"value": "Truck"
},
{
"name": "Color",
"value": "Blue"
},
{
"name": "Location",
"value": "Store"
}
];
Here is what I am trying to make the new Array look like:
var newArray = [
{
"name": "Product",
"value": "Car Boat Truck"
},
{
"name": "Color",
"value": "Blue"
},
{
"name": "Location",
"value": "Store"
}
];
In the newArray the Products are all in one object.
You can use the groupBy method to get all the elements with the same name together, then map to transform them into what you want. And pluck is useful here to combine the values in the output array.
Here's quick, simple solution:
var newArray = _.chain(myArray)
.groupBy("name")
.map(function(a) {
return {
"name": a[0].name,
"value": _.pluck(a, "value").join(" ")
};
})
.value();
Demonstration
And just for completeness, here's the non-chained version:
var newArray = _.map(_.groupBy(myArray, "name"), function(a) {
return {
"name": a[0].name,
"value": _.pluck(a, "value").join(" ")
};
});
Here's a more generalized solution that's reusable and not hard-coded. This way, you can create multiple groupBy methods for different properties of different object collections, then join the properties that you require. jsFiddle
function groupBy(groupBy) {
return function(source, joinOn) {
return _.each(_.groupBy(source, groupBy), function(val, key, context){
context[key] = _.pluck(val, joinOn).join(' ');
});
};
}
var groupByNameOn = groupBy('name');
console.log(groupByNameOn(arr, 'value'));

Categories