finding a value in an object - javascript

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.

Related

Return true if an array within an array contains specific key

I have the following the object:
items: [
{
object_a {
id: "1",
value: "somevalue1"
}
},
{
object_b {
id: "2"
value: "somevalue2"
items:[
{
nested_object_a {
id: "3"
value: "somevalue3"
},
nested_object_b {
id: "4"
value: "somevalue4"
},
}
]
}
},
]
I can check if the value key exists in the initial items array:
items.some(item => item.hasOwnProperty("value"));
To see if the value key exists in the nested object_b item array I can do the following:
items[1].object_b.items.some(item => item.hasOwnProperty("value"));
Instead of specifying which number in the array to look in I need to make the final expression dynamic. I'm certain I need to do a find or a filter on the top level items, but I've had no luck with it so far.
I found that using an every function on the items allowed me to return the boolean value I required form the array. The problem this created is any array item that didn't have the object_b key on was returning null and breaking my app. It turns out I needed to use an optional chaining operator to get around this (.?).
Thanks to #ikhvjs for linking that stackedoverflow article.
Working code:
items.every(item => {
item.object_b?.items.some(item => item.hasOwnProperty("value"));
});

Javascript filter parent array based on child containing value

I am trying to filter the parent array products based on the selected value which should be contained as the child. For example in my case I was trying to get all the product objects as an array which contained the string "iphone". It is not working for me and I can't seem to locate my error. Please may someone help.
What I have tried:
const selected = 'iphone'
const products = [
{
id: "4irnflpd0",
productItem: [ "iphone", "ipad", "kindle"],
},
{
id: "glrscb1m3s9k",
productItem: ["airpods","iphone",],
},
{
id: "uumkugk3jxof",
productItem: ["macbook","cable"]
},
]
var filtered = products.map(o=>{
o = Object.assign({},o); //Clone the object. So any changes will not affect the original array.
o.productItem.map(p=>{ //Use map to loop thru the products
p = p.filter(v=>v === selected); //Filter the products which include selected
});
return o;
})
Expected array output:
const products = [
{
id: "4irnflpd0",
productItem: [ "iphone", "ipad", "kindle"],
},
{
id: "glrscb1m3s9k",
productItem: ["airpods","iphone",],
},
]
Just a simple filter() method should work for us in this case. T further simplify, we can also use object restructuring, so instead of writing product.productItem.includes(selected), we'll only need to write productItem.includes(selected).
All we have to do is filter the source array by which items include the selected value:
const selected = 'iphone';
const products = [
{ id: "4irnflpd0", productItem: ["iphone", "ipad", "kindle"] },
{ id: "glrscb1m3s9k", productItem: ["airpods", "iphone", ] },
{ id: "uumkugk3jxof", productItem: ["macbook", "cable"] },
];
const filtered = products.filter(({productItem}) => productItem.includes(selected));
console.log(filtered);
If you'd prefer not to use Object destructuring, just swap that filter line for this more traditional one:
products.filter(p => p.productItem.includes(selected))
If you're not sure that every single item in your array will have the productItem key, then you should use optional chaining to prevent an error being thrown. This is as simple as adding ? before after property name. Here it is all put together:
products.filter(p => p.productItem?.includes(selected))
First of all no need to make a copy since with map function you allocated the result to new variable without changing the new array
So you need to do this
const filtered = products.map(p=>{
return p.productItem.includes(selected)
})
You can use the filter() methods on products array and find if the selected item is available in the productItems
const selected = 'iphone'
const products = [
{ id: "4irnflpd0", productItem: [ "iphone", "ipad", "kindle"] },
{ id: "glrscb1m3s9k", productItem: ["airpods","iPhone",] },
{id: "uumkugk3jxof", productItem: ["macbook","cable"] }
]
var filtered = products.filter(product =>
product.productItem?.includes(selected));
console.log(filtered);

How to search for partial match using index in fauna db

I have a faunadb collection of users. The data is as follows:
{
"username": "Hermione Granger",
"fullName": "Hermione Jean Granger",
"DOB": "19-September-1979",
"bloodStatus": "Muggle-Born",
"gender": "Female",
"parents": [
"Wendell Wilkins",
"Monica Wilkins"
]
}
when I use an index I have to search for the whole phrase i.e. Hermione Granger. But I want to search for just Hermione and get the result.
I came across a solution that seems to work.
The below uses the faunadb client.
"all-items" is an index setup on a collection in Fauna that returns all items in the collection
The lambda is searching on the title field
This will return any document with a title that partially matches the search term.
I know this is a bit late; I hope it helps anyone else who may be looking to do this.
const response = await faunaClient.query(
q.Map(
q.Filter(
q.Paginate(q.Match(q.Index("all_items"))),
q.Lambda((ref) =>
q.ContainsStr(
q.LowerCase(
q.Select(["data", "title"], q.Get(ref))
),
title // <= this is your search term
)
)
),
q.Lambda((ref) => q.Get(ref))
)
The Match function only applies an exact comparison. Partial matches are not supported.
One approach that might work for you is to store fields that would contain multiple values that need to be indexed as arrays.
When you index a field whose value is an array, the index creates multiple index entries for the document so that any one of the array items can be used to match entries. Note that this strategy increases the read and write operations involved.
Here's an example:
> CreateCollection({ name: "u" })
{
ref: Collection("u"),
ts: 1618532727920000,
history_days: 30,
name: 'u'
}
> Create(Collection("u"), { data: { n: ["Hermione", "Granger"] }})
{
ref: Ref(Collection("u"), "295985674342892032"),
ts: 1618532785650000,
data: { n: [ 'Hermione', 'Granger' ] }
}
> Create(Collection("u"), { data: { n: ["Harry", "Potter"] }})
{
ref: Ref(Collection("u"), "295985684233060864"),
ts: 1618532795080000,
data: { n: [ 'Harry', 'Potter' ] }
}
> Create(Collection("u"), { data: { n: ["Ginny", "Potter"] }})
{
ref: Ref(Collection("u"), "295985689713967616"),
ts: 1618532800300000,
data: { n: [ 'Ginny', 'Potter' ] }
}
> CreateIndex({
name: "u_by_n",
source: Collection("u"),
terms: [
{ field: ["data", "n"] }
]
})
{
ref: Index("u_by_n"),
ts: 1618533007000000,
active: true,
serialized: true,
name: 'u_by_n3',
source: Collection("u"),
terms: [ { field: [ 'data', 'n' ] } ],
partitions: 1
}
> Paginate(Match(Index("u_by_n"), ["Potter"]))
{
data: [
Ref(Collection("u"), "295985684233060864"),
Ref(Collection("u"), "295985689713967616")
]
}
Note that you cannot query for multiple array items in a single field:
> Paginate(Match(Index("u_by_n"), ["Harry", "Potter"]))
{ data: [] }
The reason is that the index has only one field defined in terms, and successful matches require sending an array having the same structure as terms to Match.
To be able to search for the full username and the username as an array, I'd suggest storing both the string and array version of the username field in your documents, e.g. username: 'Hermione Granger' and username_items: ['Hermione', 'Granger']. Then create one index for searching the string field, and another for the array field, then you can search either way,

JavaScript : searching an array and returning value after user input

var data = [{
id: 'A1',
name: 'Minstrels'
}, {
id: 'A2',
name: 'Bounty'
}, {
id: 3,
name: 'Crunchie'
}, {
id: 4,
name: 'bar'
}];
var rl = require('readline')
var prompts = rl.createInterface(process.stdin, process.stdout);
prompts.question('Which Product do you want to purchase? ',
function(Answer1) {
//missing code goes here in order to return Minstrels if the user
//types 'A1' etc..
}
)
I need help in my code. I have enabled user input and made an array, however, I can't think of what my code is missing.
This uses the find() array method to locate the first element matching the given predicate, then additionally handles the case where the item was not located. Because your example uses both strings and numbers for id values, we explicitly coerce each object's id to a string during comparison to simplify the strict comparison:
var item = data.find(i => ("" + i.id) === Answer1);
console.log(item ? item.name : 'No such food');

How to filter deeply stacked data inside an object(and edit\delete it afterwards)?

I have a problem here, and I can't find out how to solve it. I have an object with many levels. There is arrays with objects inside my object, and they have their arrays with objects too. Let me show you somekind of example here:
{
sections: [
{
currency_sections: [
{
positions: [
{
id: 131,
quantity: 24
},
{
id: 133,
quantity: 1
}
],
key: value,
key: value
},
{
positions: [
{
id: 136,
quantity: 2
},
{
id: 137,
quantity: 3
}
],
key: value,
key: value
}
],
key: value,
key: value
}
],
key: value,
key: value
}
I build my data via handlebars template. Which is not really important. But on my page I can change, let's say, quantity of the position. When I do that I have only id of the position I changed and new quantity.
So basically I need to filter my object to find one object in positions arrays that matches via id key and change quantity there.
Also I can delete whole position, and in that case I need to find position object with id needed and delete whole object.
The thing I can't understand is how I can filter all my data at once. And how can I manipulate unnamed object if I will find it.
And let's say I filtered it somehow. Can I return full path to that object for later use? In example - sections[0].currency_sections[1].positions[0] ? Because if I can do that than deleting and editing should be simple enough.
At this point I don't really have the time to redo everything on something more suitable like angular or ember. Although I have underscore and jquery.
Just wanted to update my question. At the end I just created a method that builds index of my elements.
function _createItemsIndex(data) {
if (!$.isEmptyObject(data)) {
$.each(data.sections, function (sectionIndex, section) {
$.each(section.currency_sections, function (curSecIndex, curSec) {
$.each(curSec.positions, function (positionIndex, position) {
_items.push({
id: position.id,
quantity: position.quantity,
price: parseFloat(position.price) || 0,
index: [sectionIndex, curSecIndex, positionIndex]
});
});
});
});
}
}
Thank you levi for your comments

Categories

Resources