Filtering array where property contains string - javascript

I'm trying to filter some JSON data to search for job roles that starts with a certain string.
The JSON looks like :
"periods": [
{
"periodName": "Week1",
"teamName": "Tango",
"roleName": "SoftwareEngineerII",
"roleExperience": "2",
"id": "cc1f6e14-40f6-4a79-8c66-5f3e773e0929"
},
...
]
I want to filter for roleName that starts with "Software" so that I can see a list of all Software Engineer levels, and it filters out other roles.
I'm not sure how to do a "starts with" or "contains" here.

You are trying to filter the array where one of the string properties contains a value... How else would you check if a string contains another string?
You could use a regex:
var str = 'SoftwareEngineerII';
if (str.match(/^software/i)) {
// it starts with 'software'
}
So you need to convert this to a predicate that could be used in your filter.
var query = Enumerable.From(data.periods)
.Where("!!$.roleName.match(/^software/i)")
.ToArray();

Related

How to return the key of an array of objects using its name

NOTE: I know what I'm attempting to do logically doesn't make sense in terms of why I want to achieve this, however I just want to know if it's possible and if so what I might be writing wrong?
I'm working with an array of objects like so:
this.animalsAndFruits = [
{
"category": "Apple",
"num1": 1287,
"num2": 12956
},
{
"category": "Panda",
"num1": 2574,
"num2": 25826
},
....
]
This may seem tedious and rather ridiculous however using the array I want to return the word 'category', not the value just the key 'category'.
I've tried
this.objectFromArray[0].category
However it only returns the value of the 0th indexed item (even though the 0th indexed item key will always have key 'category')
Is there another way I can accomplish this?
P.S. The reason why I want to get 'category' is because I need to set a variable = 'category', however I don't want to hardcode it directly like this
var someVar = 'category'
If it helps, the value in the key:value pair where the key = category is always a string (whereas all of the other values under different keys are numbers.
Maybe logic like so might work =>
if(value = string) then return key ?
Since the non-category properties have a consistent format (num#, right? at least going by the prior question), if you want to find the key which does not start with num, you can use Object.keys to get an array of keys, then .find the key matching the condition:
const animalsAndFruits = [
{
"category": "Apple",
"num1": 1287,
"num2": 12956
},
{
"category": "Panda",
"num1": 2574,
"num2": 25826
},
];
const propertyName = Object.keys(animalsAndFruits[0]).find(
key => !key.startsWith('num')
);
console.log(propertyName);
If you happen to be able to depend on the non-num key always being the first one defined in the objects, you could also use Object.keys(animalsAndFruits[0])[0].

Can you use includes() within find()?

When I try to use includes() within find() it doesn't come further than 2 items. The JSON file is valid. So I was wondering, is there a better solution since this doesn't seem to work?
async function getTheRightObject(input){
let Obj = await aJSONFile.find(item => item.AnArray.includes(input));
console.log(Obj);
return Obj;
}
let userInput = "annother one";
getTheRightObject(userInput).then(function(output){
console.log(output);
}).catch(function (err) {
//Error things
});
JSON something like:
[{
"Id": 1,
"Code": "586251af58422732b34344c340ba3",
"Input": ["official Name", "officialname", "oficial name", "officcial name"],
"Name": "Official Name",
"Flavor": "",
"Image": "https://123.com/image.png"
},
{
"Id": 2,
"Code": "597f723dceeca347a243422f9910e",
"Input": ["another one", "anotherone", "annother one", "another 1"],
"Name": "Another One",
"Flavor": "A bit of text",
"Image": "http://123.com/image2.png"
},
etc...
]
So I want to search for an object in this JSON file, which matches the users' input with the object Input of the JSON file, and sends back the Name. But this solution only seems to work for the first 2/3 items or so.
Edit:
Well, it seems I only had lower case character in the first 2 objects. In the other objects in the json file I also used upper case characters.
So my solution final is;
All object.Input = ['text1', 'text2', 'text3, 'etc'] in the json file are lower case now
use toLowerCase() on the input. Like:
let Obj = await aJSONFile.find(item => item.AnArray.includes(input.toLowerCase));
This works in my case because I know the objects are quite unique in my case. In any other cases (ie when you expect multiple objects) you can beter use the solution of Tiny Giant or varit05 down here
Here you go!
find: The find() method returns the value of the first element in the array that satisfies the provided testing function.
Documentation: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find
includes: The includes() method determines whether an array includes a certain element, returning true or false as appropriate.
Documentation: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find
To Answer your question:
Try to use for loop with if for desired data from an array of object.
Hope it helps!
It looks like you're looking for Array#filter, which returns a new array containing all elements that cause the provided function to return true, whereas Array#find returns the value of the first element that causes the provided function to return true.
In the example below, I've condensed the JSON, some of the variable names, and removed the irrelevant async/await usage to aid in readability for future readers.
let data = JSON.parse('[{"id":1,"arr":["a","aa","aaa"]},{"id":2,"arr":["b","bb","bbb"]},{"id":3,"arr":["c","cc","ccc"]},{"id":4,"arr":["a","bb","ccc"]}]');
const filter = (field, input) => data.filter(e => e[field].includes(input));
/*
* For demonstration purposes only.
* Map the result of the filter call to an array of
* matching id's, then output a human readable result
* Example output: "a: [1,4]"
*/
const test = (...args) => (console.log(`${args[1]}: ${JSON.stringify(filter(...args).map(e => e.id))}`), test);
test('arr', 'a')
('arr', 'aa')
('arr', 'aaa')
('arr', 'b')
('arr', 'bb')
('arr', 'bbb')
('arr', 'c')
('arr', 'cc')
('arr', 'ccc');
.as-console-wrapper { max-height: 100% ! important; height: 100% !important }

Efficient way to find name value pairs from JSON array in Javascript

I am currently making a call to a service which sends a response as an array of objects with name value pairs. An example of this can be seen below. There could be any amount of these name value pairs in any order but I just want to access the value for the name "name2". Is there an efficient way other than looping through each object and checking the name to obtain the corresponding value for name2?
[{"name":"name1","value":"value1"},{"name":"name2","value":"value2"}]
So from the above data set I would want an efficient way to search for name2 and get the corresponding value "value2".
Thanks
Unless you know the specific index of the object with the name name2 no.
You'll need to iterate until you find that name then you can bail out.
e.g.
var jsonData = [{"name":"name1","value":"value1"},{"name":"name2","value":"value2"}];
for(var i=0;i<jsonData.length;i++){
if(jsonData[i]['name'] == 'name2'){
console.log('The value is: ' + jsonData[i]['value']);
break;
}
}
Note that if you don't need to support Internet Explorer, you can use the Array.find() method to simplify this.
if you don't want to iterate over the array manually you can use lambda expression as the following
a =[{"name":"name1","value":"value1"},{"name":"name2","value":"value2"}] ;
//get the items that match your criteria
a.filter(item=>item.name=="name2")
//get those items' values
a.filter(item=>item.name=="name2").map(item=>item.value)
//get the first value (if you know that it's only one item that will match)
a.filter(item=>item.name=="name2").map(item=>item.value)[0]
You can use Array#find method.
var arr = [{
"name": "name1",
"value": "value1"
}, {
"name": "name2",
"value": "value2"
}];
// get the object containing name as `name2`
var obj = arr.find(function(v) {
return v.name === 'name2';
});
// get value property if object is defined
var res = obj && obj.value;
console.log(res)

Node.js take row from 2 dimensional JSON array

I have two dimensional JSON array. I can take data from first dimension like data["dimension-1"] however i cannot take data from second dimension like: data["dimension-1"]["dimension-2"]. What is the proper way to take single row from second dimension of my array?
data["dimension-1"]["dimension-2"] - seems to be rather an object - hence it should look like :
var data = {
"dimension-1" : {
"dimension-2" : 'value'
}
}
data["dimension-1"]["dimension-2"] // will display 'value'
and then your way it ok.
but if it's an array
var data =[[1,2], [3,4]]
then one should access it like (the indexes are NUMERIC - not strings or any other):
data[0][1] // will display 2
You have an object with properties that are also a mixture of arrays or objects. If you are trying to extract the ID of the data property, which is an array, then you will need to select the property, enter the array (first item is 0), which returns another object. Then just select the property.
You'll need something like the following in your use case: -
objectName.data[0].id
or
objectName["data"][0]["id"];
This is for extracting the ID from within the data attribute in data like this (that you provided): -
var objectName = {
"total_pages": 1424,
"total_rows": 1424,
"data": [
{
"id": 1525,
"television_id": 1,
// other stuff
"categories": [
{
"id": 170,
"title": "title"
},
{
"id": 4,
"title": "message"
}
]
}
]
}
A 2 dimensional JSON array looks like this:
[
["a", "b", "c"],
["d", "e", "f"],
["g", "h", "i"]
]
Say you want to access the last column in the second column. i.e. "f", then you need to access it by number not name. i.e.:
data[1][2]
EDIT:
Stictly speaking, my original answer is correct. Your 2 dimensional array may be accessed by indices.
However, knowing the format of your data now, I would recommend either:
Use a library (e.g. lodash) to give you simple and expressive ways to query your data
or create your own function. e.g.:
var category = getCategory(x.data, 1525, 170);
function getCategory(data, id, catId) {
return data
.filter(d => d.id === id)
.map(d => d.categories
.filter(c => c.id === catId)
.map(c => c.title)
.shift()
)
.shift()
}
Good luck!

Find the length of an JSON object

I have a JSON like the following.
How can I find the length of air in console,
console.log (block.number.path[i].air.length);
{ "block": [
{ "number": "36",
"path": [
{ "air": "[{\"name\":\"0\"},{\"name\":\"1\"},{\"name\":\"2\"}]" },
{ "water": "[{\"name\":\"3\"},{\"name\":\"4\"},{\"name\":\"5\"}]" },
{ "sand": "[{\"name\":\"6\"},{\"username\":\"7\"},{\"name\":\"8\"}]" }
]
}
]
}
air itself contains a JSON encoded array, which you have to decode first:
// your obj in here
var obj = { "..." : "..." };
// grab the respective length of the "air" attribute
var air = JSON.parse( obj.block[0].path[0].air );
console.log( air.length );
http://jsfiddle.net/pLAny/
You can solve this like so:
var length = JSON.parse(block.number.path[i].air).length;
console.log(length);
It kind of looks like some of that JSON got malformed. "air", "water", and "sand" are all JSON arrays...but parsed out into strings. If you're the one generating the JSON, look into that, because it doesn't seem right. As the other answers point out, it's still solvable in Javascript using JSON.parse(), as long as you can be sure your target browsers have that interface (most modern ones).
For any JSON array (anything declared using [] brackets) you can check its .length property.
Given that json is a variable containing your JSON, you can do:
json["block"][0]["path"][0]["air"].length
Block is an array, so you have to access to the element first:
a.block[0].path[0].air.length
where a is the variable where you are holding the data.

Categories