Searching a JSON formatted array - javascript

I am trying to search the below array which is in JSON format.
[{"SystemID":"62750003","ApparentPower":"822"},
{"SystemID":"62750003","ApparentPower":"822"},
{"SystemID":"62750003","ApparentPower":"807"},
{"SystemID":"62750003","ApparentPower":"796"}]
I want to first check the first element in this case "SystemID" and append all the values of "SystemID" to op1 array I have created. I am not sure how to do this, my code to search the array is below (JS file):
$(document).ready(function() {
$.ajax({
url: "http://localhost/chartjs/data.php",
method: "GET",
success: function(data) {
op1 = [];
if (data[i] == 'SystemID') {
for(var i in data) {
op1.push(data[i]['SystemID'])
}
}
}
}
}
When I run this code now, op1 is empty.
I want op1 to have all the values of SystemID from the JSON array.
UPDATE: I want to check IF the element is "SystemID" and if so, appened the first element to "op1". The first element and second element in my JSON data could change, so I want to check that first and then append the first element to "op1". Also I want to check the second element, and append the second elements value to "op2" array.

As i understand you want all the SystemID in the array op1:
const data = [{"SystemID":"62750003","ApparentPower":"822"},{"SystemID":"62750003","ApparentPower":"822"}, {"SystemID":"62750003","ApparentPower":"807"},{"SystemID":"62750003","ApparentPower":"796"}];
const op1 = data.map(item => item.SystemID);
console.log(op1);

You need something like that , you are missing the for loop
var data = [{"SystemID":"62750003","ApparentPower":"822"},
{"SystemID":"62750003","ApparentPower":"822"},
{"SystemID":"62750003","ApparentPower":"807"},
{"SystemID":"62750003","ApparentPower":"796"}]
var op1 = [];
var op2 = [];
for(let i=0; i < data.length;i++){
for(let item in data[i]){
if(item == "SystemID"){
op1.push(data[i][item])
}
if(item == "ApparentPower"){
op2.push(data[i][item])
}
}
}
console.log(op1)
console.log(op2)
if you wanna use ECMA6
let data = [{"SystemID":"62750003","ApparentPower":"822"},
{"SystemID":"62750003","ApparentPower":"822"},
{"SystemID":"62750003","ApparentPower":"807"},
{"SystemID":"62750003","ApparentPower":"796"}]
let op1 = data.map(item => item.SystemID);
let op2 = data.map(item => item.ApparentPower);
console.log(op1)
console.log(op2)
if you wanna global concept
let data = [{"SystemID":"62750003","ApparentPower":"822"},
{"SystemID":"62750003","ApparentPower":"822"},
{"SystemID":"62750003","ApparentPower":"807"},
{"SystemID":"62750003","ApparentPower":"796"}]
let data_keys = Object.keys(data[0])
let result = []
for(let item in data_keys){
result.push([])
}
for(let i=0; i < data.length;i++){
for(key in data_keys){
if(Object.keys(data[i])[key] == data_keys[key]){
result[key].push(Object.values(data[i])[key])
}
}
}
for(let k=0; k<result.length;k++){
console.log(result[k])
}
console.log(result)

You want to check if the first key in particular is SystemID ? if that's the case you could try
const data = [
{"SystemID":"62750003","ApparentPower":"822"},
{"SystemID":"62750003","ApparentPower":"822"},
{"SystemID":"62750003","ApparentPower":"807"},
{"SystemID":"62750003","ApparentPower":"796"},
{"NOTASystemID":"6sss","ApparentPower":"796"}
];
const op = data
.filter(element => Object.keys(element)[0]==="SystemID") //filtering out element with first key sysID
.map(element => element.SystemID);
console.log(op);

As per my understanding your code will be like this
var json = [{"SystemID":"62750003","ApparentPower":"822"},
{"SystemID":"62750003","ApparentPower":"822"},
{"SystemID":"62750003","ApparentPower":"807"},
{"SystemID":"62750003","ApparentPower":"796"}];
var myArray =[];
json.forEach(function (item) {
if(item.SystemID) {
myArray.push(item.SystemID);
}
});
console.log(myArray);

Try This,
var data = '[{"SystemID":"62750003","ApparentPower":"822"},{"SystemID":"62750003","ApparentPower":"822"},{"SystemID":"62750003","ApparentPower":"807"},{"SystemID":"62750003","ApparentPower":"796"}]';
var op1 = [];
$.each(JSON.parse(data),function(i,item){
op1[i] = item.SystemID;
});
console.log(op1);

Assuming you have already parsed the JSON data, you can just map through the array and use the hasOwnProperty() method to check if each object in the array has SystemID or not and if it does, push it's value to the op1 array.
Trying to retrieve elements in an object using index is not reliable since object properties are unsorted.
var data = [{"SystemID":"62750003","ApparentPower":"822"},{"SystemID":"62750003","ApparentPower":"822"},{"SystemID":"62750003","ApparentPower":"807"},{"SystemID":"62750003","ApparentPower":"796"}];
var op1 = data.map(e => {
if (e.hasOwnProperty("SystemID")) {
return e.SystemID;
} else {
// do something else since current mapped object doesn't have "SystemID"
}
});
console.log(op1);

Related

Create an array of search results

How can i get the name in the picture below?
return testData.then((data) => {
console.log(data)
var results = [];
var toSearch = params.suggestTerm;
data = data["data"]["0"];
console.log("data: ", data["0"])
for(var i=0; i<data.length; i++) {
if(data[i]["name"].indexOf(toSearch)!=-1) {
results.push(data[i]);
}
}
result of console.log(data)
No need to do this :data = data["data"]["0"];. If you are doing that you are assigning data to be the first object from the nested list. It is not an array anymore.
Just get the list in another variable and access that:
let list = data.data;
for(var i=0; i<list.length; i++) {
if(list[i]["name"].indexOf(toSearch) !== -1) {
results.push(list[i]);
}
}
The indexOf() search will be case sensitive. If that is not what you want, you can lowercase and search.
It appears you are looking to have an array only containing items that have name values in your toSearch string. If that's the case, you could use Array.filter() similar to:
return testData.then((data) => {
console.log(data)
var results = [];
var toSearch = params.suggestTerm;
if (data && data.data && data.data.length > 0){
results = data.data.filter(item =>
item.name.toLowerCase().indexOf(toSearch.toLowerCase()) > -1
)
return results;
}
This example searches case insensitive. If you wish for a case sensitive search, remove the .toLowerCase()
See Array.filter()

How to get the common values in an array

For example i am having an array of data as below
var arrData = ["40-25",null,null,"40-25","50-48",null,"30-25","40-23","50-48","30-25",null,"50-48","40-45","40-45","40-45","40-50","40-50",null,null,null,null,null,"50-48"]
i need to list the same data as below in javascript
var arrDataSorted = ["40-25","50-48","30-25","40-23","40-45","40-50","40-50"]
need only the common data that replicates also the null to be removed.
What is the best solution to solve this.
You can try using Array.prototype.filter() to remove null values and Set to get the unique values. Finally use the Spread syntax (...) to transform the set result into an array.
Try the following way:
var arrData = ["40-25",null,null,"40-25","50-48",null,"30-25","40-23","50-48","30-25",null,"50-48","40-45","40-45","40-45","40-50","40-50",null,null,null,null,null,"50-48"];
var arrDataSorted = [...new Set(arrData.filter(i => i))];
console.log(arrDataSorted);
You can create a set from an array which will automatically remove duplicates:
let arrData = ["40-25",null,null,"40-25","50-48",null,"30-25","40-23","50-48","30-25",null,"50-48","40-45","40-45","40-45","40-50","40-50",null,null,null,null,null,"50-48"];
let set = new Set(arrData);
This will still keep the null, which you can remove with a delete call, and convert back to array with the spread ... operator. The final code will be:
let set = new Set(arrData);
set.delete(null);
let distinctArr = [...set];
add the values into the set if the value is not null and convert it to array.
var arrData = ["40-25",null,null,"40-25","50-48",null,"30-25","40-23","50-48","30-25",null,"50-48","40-45","40-45","40-45","40-50","40-50",null,null,null,null,null,"50-48"];
var setData = new Set();
for(var data of arrData) {
if(data) {
setData.add(data);
}
}
var arrDataSorted = [...setData];
console.log(arrDataSorted);
Add this function to your code:
function removeCommonValues(arr) {
let result = [];
for(let i=0; i < arr.length-1; ++i) {
if(result.includes(arr[i]) === false && arr[i] !== null)
result.push(arr[i])
}
return result
}
Usage:
removeCommonValues(["40-25",null,null,"40-25","50-48",null,"30-25","40-23","50-48","30-25",null,"50-48","40-45","40-45","40-45","40-50","40-50",null,null,null,null,null,"50-48"]) // Return ["40-25", "50-48", "30-25", "40-23", "40-45", "40-50"]
var arrData = ["40-25",null,null,"40-25","50-48",null,"30-25","40-23","50-48","30-25",null,"50-48","40-45","40-45","40-45","40-50","40-50",null,null,null,null,null,"50-48"]
var set = new Set();
for ( var i = 0 ; i< arrData.length;i++ ) {
if(arrData[i]!==null) {
set.add(arrData[i]);
}
}
var newArr = [...set]
You could use array built-in reducer method, in the next code i'm starting with an empty array, and i'm only returning the items that are not null and are not already in the array.
const data = arrData.reduce((state, value) => {
if(value && !state.includes(value)) {
return [...state, value];
}
return state;
}, [])
var arrData = ["40-25",null,null,"40-25","50-48",null,"30-25","40-23","50-48","30-25",null,"50-48","40-45","40-45","40-45","40-50","40-50",null,null,null,null,null,"50-48"]
const output = [];
arrData.forEach(val => {
if(output.indexOf(val) === -1 && val !== null) {
output.push(val);
}
});
console.log(output);
The function can be in a separated file to be reused between multiple pages. Then you can call that function to filter distinct values that are not null.
var arrData = ["40-25",null,null,"40-25","50-48",null,"30-25","40-23","50-48","30-25",null,"50-48","40-45","40-45","40-45","40-50","40-50",null,null,null,null,null,"50-48"];
function fn(value,index,self){
return self.indexOf(value) === index && value;
}
console.log(arrData.filter(fn));

iterate through nested array to match IDs

I have a set of data which is nested arrays, these arrays may be empty or they may infact contain an ID, if one of the arrays ID's matches the ID im comparing it with, I want to take all of the data inside that array which matched and assign it to a variable to be used...
example:
data = [[],[],[],[],[],[],[],[],[{"id":"123","name":"DARES HOUSE 2019","startDate":null,"endDate":null,"country":null,"city":null,"type":"Event","members":null}],[],[],[],[],[],[],[],[],[],[],[]]
id = 123
matchedArray =
for (var i = 0; i < potentialEvents.length; i++) {
for (var j = 0; j < potentialEvents[i].length; j++) {
if (id === potentialEvents[i].id) {
return;
}
}
}
console.log(matchedArray)
I'm trying to have it so matchedArray will be the array with thhe matched IDs!!
if you can help, thank you a lot!
You can do this with a combination of .map, .filter and .flat
var data = [[],[],[],[],[],[],[],[],[{"id":"123","name":"DARES HOUSE 2019","startDate":null,"endDate":null,"country":null,"city":null,"type":"Event","members":null}],[],[],[],[],[],[],[],[],[],[],[]]
var id = 123;
var matchedArray = data.map( arr => {
return arr.filter(x => x.id == id);
}).flat();
console.log(matchedArray);
You can use Array#filter method to filter the inner array and Array#flatMap method to concatenate filtered array into one.
let data = [[],[],[],[],[],[],[],[],[{"id":"123","name":"DARES HOUSE 2019","startDate":null,"endDate":null,"country":null,"city":null,"type":"Event","members":null}],[],[],[],[],[],[],[],[],[],[],[]];
let id = 123;
let matchedArray = data.flatMap(arr => arr.filter(obj => obj.id == id))
console.log(matchedArray)
I'd recommend to use .some rather then .filter/.map/.flatMap. The main benefit is that it allows to stop traversing array when element is found.
On big arrays with a lot of data it will be more efficient (≈50 times faster): jsperf test
const data = [[],[],[],[],[],[],[],[],[{"id":"123","name":"DARES HOUSE 2019","startDate":null,"endDate":null,"country":null,"city":null,"type":"Event","members":null}],[],[],[],[],[],[],[],[],[],[],[]]
const id = 123;
let matchedArray = null;
data.some((a) => {
return a.some((v) => {
if (v != null && v.id == id) {
matchedArray = a;
return true;
}
});
});
console.log(matchedArray);

Issues with JSON formatting for data object in Grafana

Data is not coming in with proper JSON formatting, so I'm having to loop through items in the array to fix the formatting, parsing the changed items and I cannot use the new object(s) when everything is finished because it is no longer in an array. The data is coming in as follows:
data [datapoints: [0..1..]
target: "up{cluster="bluehills_c3260_cluster",component="atr",datacenter="bluehills",hostname="ny-153-177"...}"]
Is there an easier way to convert this using a .map function or some other method to make things cleaner and get the desired result?
I've tried several methods including .replace, .map, and .push. I've also tried JSON.stringify, but nothing else seems to work except what I currently have.
onDataReceived(data) {
var i;
for (i = 0; i < data.length; i++) { // Loop through data array
var txt = data[i].target; // Create the variable to store the data target
var j;
for (j = 0; j <= txt.length; j++) { // Loop through the data target
var newObj = txt.slice(2,j); // Remove "up"
var filteredObj = newObj // Change over to JSON format...
.replace(/=/g,' : ')
.replace(/,/g,', ')
.replace(/{/g,'{ ')
.replace(/cluster/g,'"cluster"')
.replace(/component/g,'"component"')
.replace(/datacenter/g,'"datacenter"')
}
var dataObj = filteredObj.replace(/_"cluster"/gi,'_cluster');
var finalObj = JSON.parse(dataObj);
console.log("finalObj", dataObj);
}
}
What I want is a single array with the proper JSON format for the data (target) coming in.
How about this?
const myReg = /([\w\s]+)=\"([^"]*)\"/g
const str = `data [datapoints: [0..1..] target: "up{cluster="bluehills_c3260_cluster",component="atr",datacenter="bluehills",hostname="ny-153-177"...}"]`;
let matches = null;
const resultsJson = {};
while(matches = myReg.exec(str)){
resultsJson[matches[1]] = matches[2];
}
{ cluster: 'bluehills_c3260_cluster',
component: 'atr',
datacenter: 'bluehills',
hostname: 'ny-153-177' }
Not sure if this is how you want to have the data stored but that part would be pretty easy to customize.
onDataReceived(data){
this.createCosmo(data);
}
createCosmo(data) {
var arr = $.map(data,function(value){
return value.target;
});
var arr2 = $.map(arr,function(value){
var newObj = value.slice(2); // Remove "up"
var filteredObj = newObj // Change over to JSON format
.replace(/=/g,' : ')
.replace(/,/g,', ')
.replace(/{/g,'{ ')
.replace(/cluster/g,'"cluster"')
.replace(/component/g,'"component"')
.replace(/datacenter/g,'"datacenter"')
.replace(/hostname/g,'"hostname"')
.replace(/instance/g,'"instance"')
.replace(/job/g,'"job"')
.replace(/resilience_group/g,'"resilience_group"')
.replace(/_"cluster"/gi,'_cluster')
.replace(/-"cluster"/gi,'-cluster');
var finalObj = JSON.parse(filteredObj); // Parse the Object into JSON
return finalObj;
});
}

push only unique elements in an array

I have array object(x) that stores json (key,value) objects. I need to make sure that x only takes json object with unique key. Below, example 'id' is the key, so i don't want to store other json objects with 'item1' key.
x = [{"id":"item1","val":"Items"},{"id":"item1","val":"Items"},{"id":"item1","val":"Items"}]
var clickId = // could be "item1", "item2"....
var found = $.inArray(clickId, x); //
if(found >=0)
{
x.splice(found,1);
}
else{
x.push(new Item(clickId, obj)); //push json object
}
would this accomplish what you're looking for? https://jsfiddle.net/gukv9arj/3/
x = [
{"id":"item1","val":"Items"},
{"id":"item1","val":"Items"},
{"id":"item2","val":"Items"}
];
var clickId = [];
var list = JSON.parse(x);
$.each(list, function(index, value){
if(clickId.indexOf(value.id) === -1){
clickId.push(value.id);
}
});
You can't use inArray() because you are searching for an object.
I'd recommend rewriting a custom find using Array.some() as follows.
var x = [{"id":"item1","val":"Items"},{"id":"item1","val":"Items"},{"id":"item1","val":"Items"}]
var clickId = "item1";
var found = x.some(function(value) {
return value.id === clickId;
});
alert(found);
Almost 6 years later i ended up in this question, but i needed to fill a bit more complex array, with objects. So i needed to add something like this.
var values = [
{value: "value1", selected: false},
{value: "value2", selected: false}
//there cannot be another object with value = "value1" within the collection.
]
So I was looking for the value data not to be repeated (in an object's array), rather than just the value in a string's array, as required in this question. This is not the first time i think in doing something like this in some JS code.
So i did the following:
let valueIndex = {};
let values = []
//I had the source data in some other and more complex array.
for (const index in assetsArray)
{
const element = assetsArray[index];
if (!valueIndex[element.value])
{
valueIndex[element.value] = true;
values.push({
value: element.value,
selected: false
});
}
}
I just use another object as an index, so the properties in an object will never be repated. This code is quite easy to read and surely is compatible with any browser. Maybe someone comes with something better. You are welcome to share!
Hopes this helps someone else.
JS objects are great tools to use for tracking unique items. If you start with an empty object, you can incrementally add keys/values. If the object already has a key for a given item, you can set it to some known value that is use used to indicate a non-unique item.
You could then loop over the object and push the unique items to an array.
var itemsObj = {};
var itemsList = [];
x = [{"id":"item1","val":"foo"},
{"id":"item2","val":"bar"},
{"id":"item1","val":"baz"},
{"id":"item1","val":"bez"}];
for (var i = 0; i < x.length; i++) {
var item = x[i];
if (itemsObj[item.id]) {
itemsObj[item.id] = "dupe";
}
else {
itemsObj[item.id] = item;
}
}
for (var myKey in itemsObj) {
if (itemsObj[myKey] !== "dupe") {
itemsList.push(itemsObj[myKey]);
}
}
console.log(itemsList);
See a working example here: https://jsbin.com/qucuso
If you want a list of items that contain only the first instance of an id, you can do this:
var itemsObj = {};
var itemsList = [];
x = [{"id":"item1","val":"foo"},
{"id":"item2","val":"bar"},
{"id":"item1","val":"baz"},
{"id":"item1","val":"bez"}];
for (var i = 0; i < x.length; i++) {
var item = x[i];
if (!itemsObj[item.id]) {
itemsObj[item.id] = item;
itemsList.push(item);
}
}
console.log(itemsList);
This is late but I did something like the following:
let MyArray = [];
MyArray._PushAndRejectDuplicate = function(el) {
if (this.indexOf(el) == -1) this.push(el)
else return;
}
MyArray._PushAndRejectDuplicate(1); // [1]
MyArray._PushAndRejectDuplicate(2); // [1,2]
MyArray._PushAndRejectDuplicate(1); // [1,2]
This is how I would do it in pure javascript.
var x = [{"id":"item1","val":"Items"},{"id":"item1","val":"Items"},{"id":"item1","val":"Items"}];
function unique(arr, comparator) {
var uniqueArr = [];
for (var i in arr) {
var found = false;
for (var j in uniqueArr) {
if (comparator instanceof Function) {
if (comparator.call(null, arr[i], uniqueArr[j])) {
found = true;
break;
}
} else {
if (arr[i] == uniqueArr[j]) {
found = true;
break;
}
}
}
if (!found) {
uniqueArr.push(arr[i]);
}
}
return uniqueArr;
};
u = unique(x, function(a,b){ return a.id == b.id; });
console.log(u);
y = [ 1,1,2,3,4,5,5,6,1];
console.log(unique(y));
Create a very readable solution with lodash.
x = _.unionBy(x, [new Item(clickId, obj)], 'id');
let x = [{id:item1,data:value},{id:item2,data:value},{id:item3,data:value}]
let newEle = {id:newItem,data:value}
let prev = x.filter(ele=>{if(ele.id!=new.id)return ele);
newArr = [...prev,newEle]

Categories