How to search a single cell with multiple values - javascript

I'm trying to search a JSON. Right now it functions with an exact match. I want to add multiple data to one cell - it'll look like this: "data, data2, nope, nope2". If a user searches 'data' it needs to match for data and data2.
this is the json:
[
{"car":"Mercedes, Toyota, KIA", "state":"SA", "groupName":"AHG"},
{"car":"BMW","state":"NSW","groupName":"Brighton BMW"},
{"car":"Tesla","state":"VIC","groupName":"JAMES F"},
{"car":"Audi","state":"WA","groupName":"Audi CBD","groupPhone":"1300 04"},
{"car":"Mercedes","state":"SA","groupName":"AHG","groupPhone":"1300 05"}
]
eg the 1st string of- "car":"Mercedes, Toyota, KIA" I need to return results if a user searches for Toyota. Right now it only works if the string is only "car":"Toyota"
var app = new Vue({
el: '#app',
data: {
addCar: false,
cars: [],
loading: false,
searchCar: "",
searchState: ""
},
methods: {
search: function () {
app.loading = true;
var searchQuery = {
car: encodeURIComponent(app.searchCar)
};
if (app.searchState) {
searchQuery.state = app.searchState;
};
Sheetsu.read("https://sheetsu.com/apis/v1.0su/a4d7192e71fd", {
search: searchQuery
}).then(function (data) {
console.log(data);
app.cars = data;
app.loading = false;
},
function (err) {
console.log(err);
app.cars = [];
app.loading = false;
});
},
}
})
Would be amazing if a user can search for Toyota and be delivered results for any string containing Toyota as a car :)

Simple client-side search can be implemented by passing a regular expression object to the String#match method, where the pattern of the regular expression is your query/search string:
/* Returns non-null result is "query" matches any part of item.car string */
return item.car.match(new RegExp(query, "gi"))
You could combine this with Array#filter() to aquire only items for your JSON where the car field contains the query string:
const json = [
{"car":"Mercedes, Toyota, KIA", "state":"SA", "groupName":"AHG"},
{"car":"BMW","state":"NSW","groupName":"Brighton BMW"},
{"car":"Tesla","state":"VIC","groupName":"JAMES F"},
{"car":"Audi","state":"WA","groupName":"Audi CBD","groupPhone":"1300 04"},
{"car":"Mercedes","state":"SA","groupName":"AHG","groupPhone":"1300 05"}
]
const findItem = (data, query) => {
return data.filter(item => {
return item.car.match(new RegExp(query, "gi"))
});
}
console.log("Search for Toyota", findItem(json, "Toyota"));
console.log("Search for Mercedes", findItem(json, "Mercedes"));
console.log("Search for Tesla", findItem(json, "Tesla"));
console.log("Search for Honda", findItem(json, "Honda"));
Update
To integrate the code snippet shown above with your Vue component, try this:
var app = new Vue({
el: '#app',
data: {
addCar: false,
cars: [],
loading: false,
searchCar: "",
searchState: ""
},
methods: {
search: function() {
app.loading = true;
var searchQuery = {
car: encodeURIComponent(app.searchCar)
};
if (app.searchState) {
searchQuery.state = app.searchState;
};
Sheetsu.read("https://sheetsu.com/apis/v1.0su/a4d7192e71fd", {
search: searchQuery
}).then(function(data) {
/*
Add code here
*/
data = data.filter(item => {
return item.car.match(new RegExp(app.searchCar, "gi"))
});
app.cars = data;
app.loading = false;
},
function(err) {
console.log(err);
app.cars = [];
app.loading = false;
});
},
}
})

You can use filter and includes
let arr = [{"car":"Mercedes, Toyota, KIA", "state":"SA", "groupName":"AHG"},{"car":"BMW","state":"NSW","groupName":"Brighton BMW"},{"car":"Tesla","state":"VIC","groupName":"JAMES F"},{"car":"Audi","state":"WA","groupName":"Audi CBD","groupPhone":"1300 04"},{"car":"Mercedes","state":"SA","groupName":"AHG","groupPhone":"1300 05"},{"car":"Toyota, Testing function", "state":"SA", "groupName":"AHG"}]
let selectedKey = 'car'
let selectedValue = 'Toyota'
let op = arr.filter(({[selectedKey]:key})=> key && key.includes(selectedValue))
console.log(op)

Related

how to merge arrays from 2 different arrays

this is an image from the API that returns the test results before and after each other.
Initially when the user has not entered the test result, the array result = null, After the user enters, the array will have the same result as the image below:
my problem is after user input test, and then we update field result_template can be add or remove subjects so how do i merge subjects if use edit again result_template,
If there are new subjects but no scores are available, the default is set = 0
You can watch the video for better understanding: link
desired result: image
here is my code:
const { data } = await this.$store.dispatch(
`${UserGeneral.STORE_ADMIN_USER_KEY}/getDetailSchoolResults`,
this.$route.params.id
);
const formData = data.data;
if (formData.result) {
const listResultTemplate = formData.result.result.map((item) => {
let data = {
title: item.title,
subjects: [],
files: [],
};
item.files.forEach((file) => {
data.files.push(file);
});
item.subjects.forEach((subject) => {
data.subjects.push({
name: subject.name,
scores: {
total_score: subject.scores.total_score,
medium_score: subject.scores.medium_score,
private_score: subject.scores.private_score,
},
});
});
return data;
});
this.result = listResultTemplate;
} else {
const listResultTemplate = formData.result_template.result_template.map(
(item) => {
let data = {
title: item.title,
subjects: [],
files: [],
};
item.subjects.forEach((subject) => {
data.subjects.push({
name: subject,
scores: {
total_score: 0,
medium_score: 0,
private_score: 0,
},
});
});
return data;
}
);
this.result = listResultTemplate;
}
thanks for your help !

Javascript push array inside object

How do I create the data array from my second api call result into the format I want?
I have a code like this
var github = require('octonode');
var client = github.client();
var userName = "octocat";
var repoName = "";
var branchName = "";
var data = [];
var branches = [];
client.get('/users/'+userName+'/repos', {}, function (err, status, body, headers) {
body.forEach(function(obj) {
repoName = obj.name;
//==============================
client.get('repos/'+userName+'/'+repoName+'/branches', {}, function (errx, statusx, bodyChild, headersx) {
bodyChild.forEach(function(objChild) {
branchName = objChild.name;
});
});
});
});
I have received repoName and branchName data as well.
I want my data format like
How to use
data.push({
name: repoName,
branches: 'branchName loooping here for every repoName'
});
so branches repetition data can be contained in my branches tag
Thank you
I guess you can do something like this:
var data = [];
client.get('/users/'+userName+'/repos', {}, function (err, status, body, headers) {
body.forEach(function(obj) {
repoName = obj.name;
client.get('repos/'+userName+'/'+repoName+'/branches', {}, function (errx, statusx, bodyChild, headersx) {
let elem = {"name": repoName, "branches": []}; //create json object for each repo
bodyChild.forEach(function(objChild) {
elem.branches.push(objChild.name); //push all branchs to that elem
});
data.push(elem); // add the elem to the data array
});
});
});
So in this case data is an object, that has a property name which is string, and another property branches which is array. If you want to push data to the property branches you can just call the push() function on it.
Please check the example below:
let data = {
name: "repoName",
branches: [
{
name: "foo"
}
]
}
data.branches.push(
{
name: "bar"
}
);
console.log(data);

Add elements from array to object to format fusionchart data

I want to format the data of my fusion chart based on scope variable.
I have a function which gets dates and stock values assigned to this dates.
So I have 2 arrays:
dates = [2017-04-28, 2017-04-27, 2017-04-26, 2017-04-25]
stockValues = [150.25, 147.7, 146.56, 146.49]
What I want to do is to create a new object which looks like this:
data: [{
"label": "2017-04-28",
"value": "150.25"
},
{
"label": "2017-04-27",
"value": "147.7"
},
... //and so on
]
I managed to come up with following code:
$scope.getStockData = function(stockID) {
$http.get('/stock', {
params : {
stockID : encodeURI(stockID)
}
}).then(function(response) {
$scope.stock = response.data;
var data={};
$scope.data={};
angular.forEach(response.data.dates,function(value){
data["label"] = value;
})
angular.forEach(response.data.stockValues,function(value){
data["value"] = value;
})
$scope.data = data;
}, function(response) {
$scope.showError = true;
}).finally(function() {
});
};
The problem is that this solution creates object which looks like this:
{"label":"2017-04-25","value":"146.49"}
So it takes only the last values from array.
How can I make my object look the way I want it to?
Example:
const dates = ['2017-04-28', '2017-04-27', '2017-04-26', '2017-04-25']
const stockValues = ['150.25', '147.7', '146.56', '146.49']
const r = dates.map((d, i) => Object.assign({
label: d,
value: stockValues[i]
}))
console.log(JSON.stringify(r, null, 2))
Try this, you must initialize an array, and the push at the right location.
$scope.getStockData = function(stockID) {
$http.get('/stock', {
params : {
stockID : encodeURI(stockID)
}
}).then(function(response) {
$scope.stock = response.data;
var data=[];
$scope.data=[];
angular.forEach(response.data.dates,function(value, i){
data[i]["label"] = value;
})
angular.forEach(response.data.stockValues,function(value, i){
data[i]["value"] = value;
})
$scope.data = data;
}, function(response) {
$scope.showError = true;
}).finally(function() {
});
};

Firebase orderByChild Ignored

How do I sort the following structure in Firebase by sortOrder?
categories {
{
"b": {
"name": "Banana",
"sortOrder": 2
},
"a": {
"name": "Apple",
"sortOrder": 1
}
}
}
From the documentation it looks as simple as:
ref('categories').orderByChild('sortOrder').once('value') ...
However, the first node returned is banana. It doesn't matter what string value I use. For example, the following returns the same results:
ref('categories').orderByChild('xxx').once('value') ...
Full function:
public list(): Observable<Category[]> {
let ref = firebase.database().ref('categories').orderByChild('sortOrder');
return Observable.fromPromise(<Promise<any>>ref.once('value'))
.flatMap(snapshot => {
let objects = snapshot.val();
let categories: Array<Category> = new Array();
for (let key in objects) {
let category: Category = objects[key];
category.code = key;
categories.push(category);
}
return Observable.of(categories);
}
);
}
The problem is that when you access the children via the snapshot's value's keys, the order is indeterminate.
You need to use the snapshot's forEach method:
return Observable.fromPromise(<Promise<any>>ref.once('value'))
.flatMap(snapshot => {
let categories: Array<Category> = new Array();
snapshot.forEach(childSnapshot => {
let category: Category = childSnapshot.val();
category.code = childSnapshot.key;
categories.push(category);
});
return Observable.of(categories);
}
);
Also, you could just use map and return categories.

How to set the defaults of an array that has an unknown number of objects?

I know how to set the defaults of an object:
store.currentUser = {
username: ''
}
And set new values to it:
store.getCurrentUser = () => {
const currentUser = Parse.User.current()
store.currentUser.username = currentUser.username
}
}
But I can't do that if I have an array:
store.buildings = [
// how to set the defaults here?
]
Because the number of objects that the array can contain is unknown:
store.findBuildings = () => {
const query = new Parse.Query(Building)
return query.find({
success: (buildings) => {
// _.map(buildings, (building) => building.toJSON())
// -> [ {name: 'Name 1'}, {name: 'Name 2'}, etc... ]
// how to give the new values to store.buildings?
},
error: (buildings, error) => {
console.log('Error:', error.message)
}
})
}
Is here any way to accomplish this?
Note: I can't just do buildings = [] because I need the keys to have defaults in order for the reactivity of my app to work.
Check this answer
Array.prototype.repeat= function(what, L){
while(L) this[--L]= what;
return this;
}
var A= [].repeat(0, 24);
Or using second answer
var a = Array.apply(null, Array(24)).map(function() { return /your object here/ });
// or:
var a = Array.apply(null, Array(5)).map(Boolean).map(Number);

Categories

Resources