I have a dictionary that looks a little like this:
var index = {
"Italian": [
{
"name": "Il Brigante",
"rating": "5.0"
},
{
"name": "Giardino Doro Ristorante",
"rating": "5.0"
}
],
"Mexican": [
{
"name": "Cosme",
"rating": "5.0"
}
]
}
I also have a search bar that people can enter queries into. What I want to do is take the query and search for it inside index.
Example: search = "italian", results = {"name": "Il Brigante", "rating": "5.0"}, {"name": "Giardino Doro Ristorante", "rating": "5.0"}
Is that kind of search possible? Any help would be appreciated. Thanks so much in advance. Happy 4th!
Cheers,
Theoi
You can try following
var index = {
"Italian": [{
"name": "Il Brigante",
"rating": "5.0"
},
{
"name": "Giardino Doro Ristorante",
"rating": "5.0"
}
],
"Mexican": [{
"name": "Cosme",
"rating": "5.0"
}]
};
var search = "italian";
var results = Object.keys(index).reduce(function(a, b) {
if (b.toLowerCase() === search.toLowerCase()) {
return a.concat(index[b]);
}
return a;
}, []);
console.log(results);
May Be a Requirement Later!
In case you want to for the partial match, you just need to replace
if (b.toLowerCase() === search.toLowerCase()) {
with
if(b.toLowerCase().indexOf(search.toLowerCase()) !== -1) {
For tweaking - plunker
You can use hasOwnProperty directly, but that will only return exact matches. Simplest way is to loop through the index properties and look for a match and return the resulting value.
var index = {
"Italian": [
{
"name": "Il Brigante",
"rating": "5.0"
},
{
"name": "Giardino Doro Ristorante",
"rating": "5.0"
}
],
"Mexican": [
{
"name": "Cosme",
"rating": "5.0"
}
]
}
console.log(index.hasOwnProperty('italian'));
console.log(index.hasOwnProperty('Italian'));
console.log(dictionarySearch('Italian', index));
function dictionarySearch(term, dictionary)
{
var found = false;
if (typeof dictionary === 'object') {
for(property in dictionary) {
if (dictionary.hasOwnProperty(property)) {
if (property.toLowerCase() === term.toLowerCase()) {
found = dictionary[property];
}
}
}
}
return found;
}
Check out square-bracket-notation.
This notation is also very useful when property names are to be dynamically determined (when the property name is not determined until runtime).
Source with examples
Applying this to your problem:
var index = {
"Italian": [
{
"name": "Il Brigante",
"rating": "5.0"
},
{
"name": "Giardino Doro Ristorante",
"rating": "5.0"
}
],
"Mexican": [
{
"name": "Cosme",
"rating": "5.0"
}
]
}
var query = "Italian"
var result = index[query]
console.log(index["Italian"])
I assume that there is no situation when we have indexes like 'itAlIaN'/ 'italian' / 'ITALIAN' so index is unique no matter if you have lower/upper case
var index = {
"Italian": [
{
"name": "Il Brigante",
"rating": "5.0"
},
{
"name": "Giardino Doro Ristorante",
"rating": "5.0"
}
],
"Mexican": [
{
"name": "Cosme",
"rating": "5.0"
}
]
}
// function to normalize index by having keys lowercase
function lowercaseIndex (obj) {
var keys = Object.keys(obj);
var n = keys.length;
var normalized = {};
while (n--) {
var key = keys[n];
normalized[key.toLowerCase()] = obj[key];
}
return normalized;
}
index = lowercaseIndex(index);
function search(needle) {
return index[needle.toLowerCase()] || "No results";
}
// tests
console.log(search('Italian')); // output: [{"name":"Il Brigante","rating":"5.0"},{"name":"Giardino Doro Ristorante","rating":"5.0"}]
console.log(search('italian')); // output: [{"name":"Il Brigante","rating":"5.0"},{"name":"Giardino Doro Ristorante","rating":"5.0"}]
console.log(search('iTaLiAn')); // output: [{"name":"Il Brigante","rating":"5.0"},{"name":"Giardino Doro Ristorante","rating":"5.0"}]
console.log(search('mexican')); // output: [{"name":"Cosme","rating":"5.0"}]
console.log(search('English')); // output: "No results"
Related
I create a Pokédex app, but i ran in some Problems with the double type Pokémon:
I call pokeapi twice to 2 endpoints (one for each Type), and i need to compare the Results in different Ways.
let a = {
"double_damage_from": [
{
"name": "ground",
"url": "https://pokeapi.co/api/v2/type/5/"
},
{
"name": "rock",
"url": "https://pokeapi.co/api/v2/type/6/"
},
{
"name": "water",
"url": "https://pokeapi.co/api/v2/type/11/"
}
],
"half_damage_from": [
{
"name": "bug",
"url": "https://pokeapi.co/api/v2/type/7/"
},
{
"name": "steel",
"url": "https://pokeapi.co/api/v2/type/9/"
},
{
"name": "fire",
"url": "https://pokeapi.co/api/v2/type/10/"
},
{
"name": "grass",
"url": "https://pokeapi.co/api/v2/type/12/"
},
{
"name": "ice",
"url": "https://pokeapi.co/api/v2/type/15/"
},
{
"name": "fairy",
"url": "https://pokeapi.co/api/v2/type/18/"
}
],
"no_damage_from": []
};
let b = {
"double_damage_from": [
{
"name": "fighting",
"url": "https://pokeapi.co/api/v2/type/2/"
},
{
"name": "ground",
"url": "https://pokeapi.co/api/v2/type/5/"
},
{
"name": "steel",
"url": "https://pokeapi.co/api/v2/type/9/"
},
{
"name": "water",
"url": "https://pokeapi.co/api/v2/type/11/"
},
{
"name": "grass",
"url": "https://pokeapi.co/api/v2/type/12/"
}
],
"half_damage_from": [
{
"name": "normal",
"url": "https://pokeapi.co/api/v2/type/1/"
},
{
"name": "flying",
"url": "https://pokeapi.co/api/v2/type/3/"
},
{
"name": "poison",
"url": "https://pokeapi.co/api/v2/type/4/"
},
{
"name": "fire",
"url": "https://pokeapi.co/api/v2/type/10/"
}
],
"no_damage_from": []
};
I need to Compare the Data and get the Matches in a array.
This works fine and i got the 4x, 1x, and 1/4x damage in a array:
getMatch(a, b) {
let matches = [];
for (let i = 0; i < a.length; i++) {
for (let e = 0; e < b.length; e++) {
if (a[i].name === b[e].name) matches.push(a[i]);
}
}
return matches;
}
compareTypes(a, b) {
let four_damage_from = this.getMatch(a.double_damage_from, b.double_damage_from);
let double_damage_from = [];
let normal_damage_from = this.getMatch(a.double_damage_from, b.half_damage_from);
let half_damage_from = [];
let quarter_damage_from = this.getMatch(a.half_damage_from, b.half_damage_from);
let no_damage_from = this.getMatch(a.no_damage_from, b.no_damage_from);
let matches = { four_damage_from, double_damage_from, normal_damage_from, half_damage_from, quarter_damage_from, no_damage_from };
return matches;
}
to find the correct types for double_damage_from i have to merge a.double_damage_from and b.double_damage_from e.g. to c.double_damage_from. then i have to remove from c.double_damage_from all types that are in four_damage_from, normal_damage_from, quarter_damage_from, no_damage_from to get the correct 2x types, the same with half_damage_from.
I tried many solution but i didn't figure out how to solve this.
greetings Raphi
It Works with lodash, i need to think a bit about but basically works.
removeMatch(union, remove, double = false) {
union = _.differenceBy(union, remove.four_damage_from, 'name');
union = _.differenceBy(union, remove.normal_damage_from, 'name');
union = _.differenceBy(union, remove.quarter_damage_from, 'name');
// union = _.differenceBy(union, remove.no_damage_from, 'name');
if(double) {
union = _.differenceBy(union, remove.half_damage_from, 'name');
} else {
union = _.differenceBy(union, remove.double_damage_from, 'name');
}
return union;
}
Trying, find and return a value from array using JavaScript- with dynamic inputs
const drawers = [
{
"name": "locations",
"values": [
{
"value": "dana-point-ca",
"label": "Dana Point, CA"
},
{
"value": "bronx-new-york",
"label": "Bronx, New York"
},
{
"value": "new-york-ny",
"label": "New York, NY"
}
]
},
{
"name": "programAreas",
"values": [
{
"value": "coral-conservation",
"label": "CORAL CONSERVATION"
}
]
}
]
Input keys are dynamic, if it is locations and value is bronx-new-york then it should return Bronx, New York;
let lbl = drawers.find(o => o.name === 'string 1').label;
Use array.find in each values until you find the answer.
const drawers = [
{
"name": "locations",
"values": [
{
"value": "dana-point-ca",
"label": "Dana Point, CA"
},
{
"value": "bronx-new-york",
"label": "Bronx, New York"
},
{
"value": "new-york-ny",
"label": "New York, NY"
}
]
},
{
"name": "programAreas",
"values": [
{
"value": "coral-conservation",
"label": "CORAL CONSERVATION"
}
]
}
]
function getLabel(x) {
for (const nameValues of drawers) {
const values = nameValues.values
const item = values.find(v => v.value === x)
if (item !== undefined) {
return item.label
}
}
}
getLabel("bronx-new-york") // 'Bronx, New York'
getLabel("coral-conservation") // 'CORAL CONSERVATION'
getLabel("Value that does not exist") // undefined
for(let i = 0 ; i < drawers.length ; i++){
let lbl = drawers[i].values.find(o => o.label === "Bronx, New York").label;
console.log(lbl)
}
There is a couple of ways to achieve that. As below, you will get all the possible results. However, you might need to deconstruct the arrays in order to get the strings.
const drawers = [
{
"name": "locations",
"values": [
{
"value": "dana-point-ca",
"label": "Dana Point, CA"
},
{
"value": "bronx-new-york",
"label": "Bronx, New York"
},
{
"value": "new-york-ny",
"label": "New York, NY"
}
]
},
{
"name": "programAreas",
"values": [
{
"value": "coral-conservation",
"label": "CORAL CONSERVATION"
}
]
}
]
const enteredValue = "bronx-new-york";
const resultArrays = []
const onSearchLocation = () => {
drawers.find(location => {
const labels = location.values.map((place => {
const array = [];
if(place.value === enteredValue) {
array.push(place.label);
}
if(array.length > 0) {
resultArrays.push(array);
}
}
))
})}
onSearchLocation();
console.log(resultArrays);
I use find with combination of map.
const d = [
{
"name": "locations",
"values": [
{
"value": "dana-point-ca",
"label": "Dana Point, CA"
},
{
"value": "bronx-new-york",
"label": "Bronx, New York"
},
{
"value": "new-york-ny",
"label": "New York, NY"
}
]
},
{
"name": "programAreas",
"values": [
{
"value": "coral-conservation",
"label": "CORAL CONSERVATION"
}
]
}
]
let r = d.find(el => el.name === 'locations').values
let re = r.map(v => {
if (v.value == 'bronx-new-york') {
return v.label
}
})
result = re.filter(e => e)
console.log(result)
I have an object
{
"input":{
"id": "7879",
"inputType": "9876",
"streamName": "870"
},
"transformation":{
"id": "7",
"dependencies": [
"8i"
],
"dropColumns": "hkj",
"processor": "hgf"
},
"output": {
"id": "v",
"saveMode": "uyt",
"dependentIds": [
"h"
],
"outPartition":[
"hg"
]
}
}
Basically every value leaving the key I have to put it in an array. So input, transformation, output values(which are objects) should be placed inside array.
Expected Output:
{
"input": [
{
"id": "7879",
"inputType": "9876",
"streamName": "870"
}
],
"transformation":[
{
"id": "7",
"dependencies": [
"8i"
],
"dropColumns": "hkj",
"processor": "hgf"
}
],
"output":[
{
"id": "v",
"saveMode": "uyt",
"dependentIds": [
"h"
],
"outPartition":[
"hg"
]
}
]
}
I tried iterating using the for in loop but was not able to achieve the expected output how should I place the values(object) inside array
var arr = [];
for(key in obj){
arr.push(Object.assign(obj[key],{name: key}))
}
You mean this (although not sure why you would need this)?
const input = {
"input":{
"id": "7879",
"inputType": "9876",
"streamName": "870"
},
"transformation":{
"id": "7",
"dependencies": [
"8i"
],
"dropColumns": "hkj",
"processor": "hgf"
},
"output": {
"id": "v",
"saveMode": "uyt",
"dependentIds": [
"h"
],
"outPartition":[
"hg"
]
}
}
Object.keys(input).forEach(key => input[key] = [input[key]] )
console.log(input)
According to the output of the object you provided, a simple implementation of looping the elements and creating the keys as arrays can be:
for(key in obj){
obj[key] = [obj[key]];
}
You could rebuild it using the reduce function if you want to do it immutable:
The reduce() method executes a reducer function (that you provide) on each element of the array, resulting in single output value.
More info see: MDN Webdocs - reduce()
const data = {
"input":{
"id": "7879",
"inputType": "9876",
"streamName": "870"
},
"transformation":{
"id": "7",
"dependencies": ["8i"],
"dropColumns": "hkj",
"processor": "hgf"
},
"output": {
"id": "v",
"saveMode": "uyt",
"dependentIds": ["h"],
"outPartition":["hg"]
}
};
const customFormat = (data) => Object.keys(data).reduce((object, key) => {
object[key] = [data[key]];
return object
}, {});
console.log(customFormat(data));
How can I display the members.Rating for "Jones, Jim"? I have tried the syntax: echo members[$temp].Rating but it doesn't work.
let $temp = "Jones, Jim";
var members = [
{ "Rating": "1500", "Name": "Williams, Bill"},
{ "Rating": "2000", "Name": "Smith, Paul" },
{ "Rating": "1000", "Name": "Jones, Jim" },
{ "Rating": "1750", "Name": "Reynolds, Beverly" } ]
Use Array.find:
let $temp = "Jones, Jim";
var members = [
{ "Rating": "1500", "Name": "Williams, Bill"},
{ "Rating": "2000", "Name": "Smith, Paul" },
{ "Rating": "1000", "Name": "Jones, Jim" },
{ "Rating": "1750", "Name": "Reynolds, Beverly" } ]
console.log(
members.find(x => x.Name === $temp).Rating
)
You can't directly reference a member of an array by value, only by index.
So, you'll have to use the find method, like so:
const tempMember = members.find(p => p.Name === $temp)
const tempMemberRating= tempMember && tempMember.Rating
Note that if find doesn't find the element you want, it will return undefined. This makes the mult-line approach necessary, as simply calling it all in one line could result in a TypeError. e.g.:
members.find(p => p.Name === "Johnson, Jimmy").Rating
Since find returns undefined here, you're attempting to reference undefined.Rating, which will throw an error.
Try this:
For (var i=0 ;i <members.length ;i++){
If ( members[i].Name == $temp ){
console.log (members[i].Raiting);
}
}
I have 2 objects, a course list and a user.
The course list is an array with a lot of courses:
[
{
"id": 12345,
"title": "Some title",
"type": [
{
"id": 4700,
"slug": "someType",
"name": "someTypeName"
}
],
"difficulty": [
{
"id": 4704,
"slug": "4",
"name": "hard"
}
],..
},
{...}
The user have also some fields:
{
"difficulty": 4, // the difficulty->slug
"type": "someType" // the type->slug
}
My task:
I want to find the best match between the courses and the user.
In this example the user is looking for type.slug == someType and a difficulty.slug == 4. The slug is always the search term.
My first attempt was:
courseList.filter((course) => {
if (course.type.indexOf(that.userData.type) != -1) {
return course; // dont work
}
});
Edit: I need to display the name and the id properties in the front-end and the "slug" is always the search term.
The filter function takes a function (in your case the arrow function) that returns a boolean so try this instead:
var filterredList = courseList.filter(course => {
return course.type.filter(type => type.slug == that.userData.type).length > 0
&& course.difficulty.filter(difficulty => difficulty.slug == that.userData.difficulty).length > 0
});
You need to compare the slug properties against the user data.
The trick here is to make sure you are filtering the arrays and checking the count.
var courseList = [
{
"id": 12345,
"title": "Some title",
"type": [
{
"id": 4700,
"slug": "someType",
"name": "someTypeName"
}
],
"difficulty": [
{
"id": 4704,
"slug": "4",
"name": "hard"
}
]
},
{
"id": 12346,
"title": "Another title",
"type": [
{
"id": 4701,
"slug": "anotherType",
"name": "anotherTypeName"
}
],
"difficulty": [
{
"id": 4704,
"slug": "4",
"name": "hard"
}
]
}
];
var userData = {
type: 'someType',
difficulty: 4
};
var filteredList = courseList.filter(o =>
o.type.filter(t => t.slug === userData.type).length > 0
&& o.difficulty.filter(d => d.slug === userData.difficulty.toString()).length > 0
);
// Print just the titles of the filtered list
console.log(filteredList.map(o => o.title));