How can I add an element in object at certain position? - javascript

I have this object:
var ages = [{
"getasafieldDetail": {
"id": "xxx",
"asaentrySet": [{
"result": "ON",
"buy": {
"username": "Dis"
},
"offerSet": [{
"createdStr": "2001-08-09 at 11:52 pm",
"value": 5.0
}]
}]
}
}];
and i want to add an element and have an output like this:
var ages = [{
"getasafieldDetail": {
"id": "xxx",
"asaentrySet": [{
"result": "ON",
"buy": {
"username": "Dis"
},
"land": "111", // THIS <<<<------------
"offerSet": [{
"createdStr": "2001-08-09 at 11:52 pm",
"value": 5.0
}]
}]
}
}];
i tried using splice but not works...
ages.splice(ages[0]['getasafieldDetail']['asaentrySet'][0]['offerSet'],0,'"land": "111"');
ages.join();

There is the handy syntax of Destructuring assignments which helps with cutting and reassembling objects.
Edit
#FireFuro99 did point to the ES6/ES2015 spec which explicitly states how to preserve/handle an object's key-order at the object's creation time.
Thus one can say ...
Every JS engine which does support Destructuring assignment has to respect too any object's key order from/at this object's creation time.
const ages = [{
getasafieldDetail: {
id: "xxx",
asaentrySet: [{
result: "ON",
buy: {
username: "Dis",
},
offerSet: [{
createdStr: "2001-08-09 at 11:52 pm",
value: 5.0,
}],
}],
},
}];
const { result, buy, ...rest } = ages[0].getasafieldDetail.asaentrySet[0];
ages[0].getasafieldDetail.asaentrySet[0] = {
result,
buy,
land: "111",
...rest,
};
console.log({ ages });
.as-console-wrapper { min-height: 100%!important; top: 0; }

Splice only works on Arrays.
To make this work, convert your Object to an Array using Object.entries(), then use splice, and then convert it back to an object using Object.fromEntries().
const entrySet = Object.entries(ages[0]['getasafieldDetail']['asaentrySet'][0]);
entrySet.splice(2,0, ["land", "111"]);
ages[0]['getasafieldDetail']['asaentrySet'][0] = Object.fromEntries(entrySet);
This will insert the key-value pair at the the specified position.
The advantage this has over the destructuring assignment is, that you can specify the index, whereas destructuring is pretty hardcoded.

ages[0]["getasafieldDetail"]["asaentrySet"][0].land = '111' will create the key land in the first object in asaentrySet and assign the value 111. Key order is not guaranteed
var ages = [{
"getasafieldDetail": {
"id": "xxx",
"asaentrySet": [{
"result": "ON",
"buy": {
"username": "Dis"
},
"offerSet": [{
"createdStr": "2001-08-09 at 11:52 pm",
"value": 5.0
}]
}]
}
}];
ages[0]["getasafieldDetail"]["asaentrySet"][0].land = '111'
console.log(ages)

When it is an array of objects you could simple, add, passing the position that you want by editing the array like the example below:
let land = {land: 1111}
let ages = [{'a':11},'2', 'wd']
let new =[]
new.push(ages[1])
new.push(land)
ages[1] = new
console.log(ages)
output:
(3) [{…}, Array(2), "wd"]
You get what you want from the array, edit it, and put back in the same position, may it can help.

Related

How do I convert a nested array to a 'keyed' array in JavaScript?

I have a nested array that looks like this:
[["Organisation","ID","Name"],["ACME","123456","Bart Simpson"],["ACME","654321","Ned Flanders"],["ACME","1234","Edna Kabappel"],["Yahoogle","666666","Bon Scott"],["Yahoogle","99999","Neil Young"],["Yahoogle","111111","Shania Twain"]]
The first value in each array is the name of an organisation that an ID and name can belong to.
I am trying to find the simplest way to group all instances where an ID and name belong to the same company, under one 'key'.
So the above would result in something like this:
{
"ACME": [
{
"ID": 123456,
"Name": "Bart Simpson"
},
{
"ID": 654321,
"Name": "Ned Flanders"
},
{
"ID": 1234,
"Name": "Edna Kabappel"
}
],
"Yahoogle": [
{
"ID": 666666,
"Name": "Bon Scott"
},
{
"ID": 99999,
"Name": "Neil Young"
},
{
"ID": 111111,
"Name": "Shania Twain"
}
]
}
I have been playing around with for loops but I'm ending up with many many lines of code, trying to detect when the company name is different from the previous, and getting into a real mess with things.
I have searched a lot here trying to find something similar but have not had any luck.
I have only just started coding again for person interest after about 18 years and I'm very novice again.
Thank you in advance for any assistance.
lot of solutions to arrive at same result, one using lambda and reduce: this is a generic solution, just adapt the output push to build your final json.
const datas = [
["Organisation", "ID", "Name"],
["ACME", "123456", "Bart Simpson"],
["ACME", "654321", "Ned Flanders"],
["ACME", "1234", "Edna Kabappel"],
["Yahoogle", "666666", "Bon Scott"],
["Yahoogle", "99999", "Neil Young"],
["Yahoogle", "111111", "Shania Twain"]
];
const titles = datas.shift()
const groupBy = (x,f)=>x.reduce((a,b)=>((a[f(b)]||=[])
.push({[titles[1]]:b[1], [titles[2]]:b[2]}),a),{});
const result = groupBy(datas, v => v[0])
console.log(result)
Using Array.reduce. Please check if this works for you. In the below approach ID and Name is hard coded. You can try writing a generic dynamic approach which handle any number of params like ID, Name, Age etc.
const myArray = [
["Organisation", "ID", "Name"],
["ACME", "123456", "Bart Simpson"],
["ACME", "654321", "Ned Flanders"],
["ACME", "1234", "Edna Kabappel"],
["Yahoogle", "666666", "Bon Scott"],
["Yahoogle", "99999", "Neil Young"],
["Yahoogle", "111111", "Shania Twain"]
];
const obj = myArray.reduce((acc, value, index) => {
if (index === 0) return acc;
const key = value[0];
if (!acc[key]) {
acc[key] = [];
}
acc[key].push({
ID: value[1],
Name: value[2]
});
return acc;
}, {});
console.log(obj);
In order to achieve what you want, you can follow below steps:
Create an object to store your result.
While you are running the loop you have to check whether name of the organization exists as a key in the object and add it if it does not, initializing it to an empty array. Then push the result you want to store into that array.
Below is a sample implementation, assuming your data is stored in data:
var result = {};
for(var i=1; i < data.length; i++){
if(!result.hasOwnProperty(data[i][0])){
result[data[i][0]] = [];
}
result[data[i][0]].push({ "ID": data[i][1], "Name": data[i][2]});
}

Best way to create new object from existing object with certain values

What is the best way to create new object from existing object with certain values, I mean i have one onbject and i want to create a new one with only the values that i need;
For example;
Existing object
data = [{
"ID": "234324234",
"calldate": "2018-03-25",
"callend": "2018-03-25",
"duration": "00:32",
"connect_duration": "00:01",
"progress_time": "2",
"first_rtp_time": "2",
"caller": "3243242342",
"caller_domain": "XXX.XXXX.XXX",
}, {
"ID": "5675675",
"calldate": "2018-03-12",
"callend": "2018-03-12",
"duration": "00:45",
"connect_duration": "00:04",
"progress_time": "2",
"first_rtp_time": "2",
"caller": "878678865",
"caller_domain": "XXX.XXXX.XXX",
}]
new Object required;
new_object = [{
"ID": "234324234",
"calldate": "2018-03-25",
"callend": "2018-03-25",
"caller": "3243242342",
}, {
"ID": "5675675",
"calldate": "2018-03-12",
"callend": "2018-03-12",
"caller": "878678865",
}]
you can do something like that by using map function
const new_object = data.map(({ ID, calldate, callend, caller }) => {
return { ID, calldate, callend, caller };
});
You can use class-transformer.
Create a class with all the properties you need
Convert plain (literal) objects to class (constructor) objects with proper options.
You can also look at the implementation of plainToClass and implement your own.

Filter out objects in array if one value is the same

I am fetching data from an api that, sometimes, gives me multiple objects with the same values, or very similar values, which I want to remove.
For example, I might get back:
[
{
"Name": "blah",
"Date": "1992-02-18T00:00:00.000Z",
"Language": "English",
},
{
"Name": "blahzay",
"Date": "1998-02-18T00:00:00.000Z",
"Language": "French",
}, {
"Name": "blah", // same name, no problem
"Date": "1999-02-18T00:00:00.000Z", // different date
"Language": "English", // but same language
},
]
So I want to check that no two objects have a key with the same "Language" value (in this case, "English").
I would like to get the general process of filtering out the entire object if it's "Language" value is duplicated, with the extra issue of not having the same number of objects returned each time. So, allowing for dynamic number of objects in the array.
There is an example here:
Unexpeected result when filtering one object array against two other object arrays
but it's assuming that you have a set number of objects in the array and you are only comparing the contents of those same objects each time.
I would be looking for a way to compare
arrayName[eachObject].Language === "English"
and keep one of the objects but any others (an unknown number of objects) should be filtered out, most probably using .filter() method along with .map().
The below snippets stores the languages that have been encountered in an array. If the current objects language is in the array then it is filtered out. It makes the assumption that the first object encountered with the language is stored.
const objs = [
{
"Name": "blah",
"Date": "1992-02-18T00:00:00.000Z",
"Language": "English",
},
{
"Name": "blahzay",
"Date": "1998-02-18T00:00:00.000Z",
"Language": "French",
}, {
"Name": "blah", // same name, no problem
"Date": "1999-02-18T00:00:00.000Z", // different date
"Language": "English", // but same language
},
],
presentLanguages = [];
let languageIsNotPresent;
const objsFilteredByLanguage = objs.filter(function (o) {
languageIsNotPresent = presentLanguages.indexOf(o.Language) == -1;
presentLanguages.push(o.Language);
return languageIsNotPresent;
});
console.log(objsFilteredByLanguage);
You could take a hash table and filter the array by checking Name and Language.
var array = [{ Name: "blah", Date: "1992-02-18T00:00:00.000Z", Language: "English" }, { Name: "blahzay", Date: "1998-02-18T00:00:00.000Z", Language: "French" }, { Name: "blah", Date: "1999-02-18T00:00:00.000Z", Language: "English" }],
hash = {},
result = array.filter(({ Name, Language }) => {
var key = `${Name}|${Language}`;
if (!hash[key]) return hash[key] = true;
});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Using Set makes it easy to remove duplicates for as many keys as you like. I tried to be as verbose as possible so that each step was clear.
var objects = [{ "Name": "blah", "Date": "1992-02-18T00:00:00.000Z", "Language": "English", }, { "Name": "blah", "Date": "1998-02-18T00:00:00.000Z", "Language": "French", }, { "Name": "blah", "Date": "1999-02-18T00:00:00.000Z", "Language": "English" }];
function uniqueKeyVals(objects, key) {
const objVals = objects.map(object => object[key]); // ex. ["English", "French", "English"]
return objects.slice(0, new Set(objVals).size); // ex. { "English", "French" }.size = 2
}
function removeKeyDuplicates(objects, keys) {
keys.forEach(key => objects = uniqueKeyVals(objects, key));
return objects;
}
// can also use uniqueKeyVals(key) directly for just one key
console.log("Unique 'Language': \n", removeKeyDuplicates(objects, ["Language"]));
console.log("Unique ['Language', 'Name']: \n", removeKeyDuplicates(objects, ["Language", "Name"]));
I would use the underscore module for JavaScript and the unique function in this scenario. Here is a sample array of data objects:
let data = [{
name: 'blah',
date: Date.now(),
language: "en"
},
{
name: 'noblah',
date: Date.now(),
language: 'es'
},
{
name: 'blah',
date: Date.now(),
language: 'en'
}];
Then we can use the unique function in the underscore library to only return a copy of the data that has unique values associated with the language key:
const result = _.unique(data, 'language');

Filtering and returning parent object using lodash chain

I want to use Lodash chain function to filter through an arrays nested array items and then return the full parent object.
Here is some dummy data from my use case to illustrate my issue:
const capital = [
{
"financeCategory": "Loans",
"financeCategoryId": "22HM6fFFwx9eK2P42Onc",
"financeElements": [
{
"financeCategoryId": "22HM6fFFwx9eK2P42Onc",
"financeElementId": "JQiqqvGEugVQuI0fN1xQ",
"financeElementTitle": "Convertible loan",
"data": [
{
"month": 1,
"value": 100,
"year": "2020"
},
{
"month": 1,
"value": 100,
"year": "2019"
},
],
}
]
},
{
"financeCategory": "Investments",
"financeCategoryId": "JtnUsk5M4oklIFk6cAlL",
"financeElements": []
},
{
"financeCategory": "Ownerships Contribution",
"financeCategoryId": "PaDhGBm5uF0PhKJ1l6WX",
"financeElements": []
}
];
I want to filter on the "data" array within the financeElements and then return full expense object with the filter applied on "data".
Let's say I want to manipulate the expense object and only get the data on the financeElements that have the year 2020. I've tried like so:
const expenseFiltered: any = _.chain(expenses)
.flatMap('financeElements')
.flatMap('data')
.filter({year: '2020' as any}).value();
But that just gives me the filtered "data" objects.
Output:
[{
"month": 1,
"value": 100,
"year": "2020"
}]
Now I know there are ways that I could use that to produce the full object with the filtered data, but I really want to do this in just one simple _.chain command
Desired output
[
{
"financeCategory": "Loans",
"financeCategoryId": "22HM6fFFwx9eK2P42Onc",
"financeElements": [
{
"financeCategoryId": "22HM6fFFwx9eK2P42Onc",
"financeElementId": "JQiqqvGEugVQuI0fN1xQ",
"financeElementTitle": "Convertible loan",
"data": [
{
"month": 1,
"value": 100,
"year": "2020"
}
],
}
]
},
{
"financeCategory": "Investments",
"financeCategoryId": "JtnUsk5M4oklIFk6cAlL",
"financeElements": []
},
{
"financeCategory": "Ownerships Contribution",
"financeCategoryId": "PaDhGBm5uF0PhKJ1l6WX",
"financeElements": []
}
]
Is this possible using lodash chain?
A chain is used to transform a structure in several steps. In your case, you don't want to change the structure. You can use nested Array.map() (or lodash's _.map()) calls to iterate and rebuild the structure, and internally _.filter() the data:
const capital = [{"financeCategory":"Loans","financeCategoryId":"22HM6fFFwx9eK2P42Onc","financeElements":[{"financeCategoryId":"22HM6fFFwx9eK2P42Onc","financeElementId":"JQiqqvGEugVQuI0fN1xQ","financeElementTitle":"Convertible loan","data":[{"month":1,"value":100,"year":"2020"},{"month":1,"value":100,"year":"2019"}]}]},{"financeCategory":"Investments","financeCategoryId":"JtnUsk5M4oklIFk6cAlL","financeElements":[]},{"financeCategory":"Ownerships Contribution","financeCategoryId":"PaDhGBm5uF0PhKJ1l6WX","financeElements":[]}];
const expenseFiltered = capital.map(ex => ({
...ex,
financeElements: ex.financeElements.map(fe => ({
...fe,
data: _.filter(fe.data, { year: '2020' })
}))
}));
console.log(expenseFiltered);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>

How to parse/filter data from JSON file in Javascript

Is there any way to parse/filter the data present in JSON file in a Javascript file.
Basically, I am calling JSON file into my local javascript. I am having trouble in reading specific data and printing.
Can anyone please help.
JSON file contains:
{
"Data": [
{
"name": "John",
"age": 30
},
{
"joined on":"Jan 2015",
"working on": "Automation",
}
]
}
I am trying to read the above JSON file as:
var jfile = require("./Example.json");
var test = JSON.parse(JSON.stringify(jfile))
console.log(test)
I get the output like this:
{ Data:
[ { name: 'John', age: 30 },
{ 'joined on': 'Jan 2015', 'working on': 'Automation' } ] }
From the above, I am interested in accessing/filtering out only one i.e. "name". I would like to print only the value "John" to the console.
I have tried to use the ".filter" method to the JSON.parse method but it throws me an error as:
JSON.parse(...).filter is not a function
Is there any way to perform this activity?
You can access it using . dot notation
var a = {
"Data": [{
"name": "John",
"age": 30
},
{
"joined on": "Jan 2015",
"working on": "Automation",
}
]
}
console.log(a.Data[0].name)
filter is an array method.
JSON.parse(...) will not give you an array. It will give you an object with a Data property. The value of that property is an array.
JSON.parse(...).Data.filter.
You can't just ignore parts of your data structure.
If you have multiple items in your array of different shapes, you can use this
Access the Data key with json.Data
map your array to transform its items into names
apply filter(Boolean) to take out those who are undefined
In your case you'll end up with an array containing only one name John
const getName = json => json.Data.map(x => x.name).filter(Boolean);
const json = {
"Data": [{
"name": "John",
"age": 30
},
{
"joined on": "Jan 2015",
"working on": "Automation",
}
]
};
console.log(getName(json));
Your JSON's main level is an object (not an array) and only arrays have .filter method.
So filter the array under Data key:
var test = JSON.parse(JSON.stringify(jfile)).Data.filter(/*something*/);
But better if you aren't re-parse JSON:
var test = jfile.Data.filter(/*something*/);
As Quentin mentioned in his comment, What is the use of below statement ?
var test = JSON.parse(JSON.stringify(jfile))
You can directly access the name property from the response.
Try this :
var obj = {
"Data": [{
"name": "John",
"age": 30
},
{
"joined on": "Jan 2015",
"working on": "Automation"
}
]
};
// Solution 1
console.log(obj.Data.map(item => item.name).filter(Boolean));
// Solution 2
console.log(obj.Data.filter(item => item.name).map(elem => elem.name));

Categories