How to convert url array query to object in Javascript - javascript

I have an URL with query params like this:
myLocalSite/?attributes%5B0%5D%5Bname%5D=customer_property_number&attributes%5B0%5D%5Bop%5D=equal&attributes%5B0%5D%5Bvalue%5D=12&attributes%5B1%5D%5Bname%5D=feedback_tags&attributes%5B1%5D%5Bop%5D=in&attributes%5B1%5D%5Bvalue%5D=test+1%2Cwww
after JSON parsing it convert into next structure
{
attributes[0][name]: "customer_property_number"
attributes[0][op]: "equal"
attributes[0][value]: "12"
attributes[1][name]: "feedback_tags"
attributes[1][op]: "in"
attributes[1][value]: "test 1,www"
}
In the end, I need an array that look like this:
attributes = [
{
name: 'customer_property_number',
op: 'equal',
value: '12',
},
{
name: 'feedback_tags',
op: 'in',
value: 'test 1, www',
},
]
Now does anyone know how I can then put these items into attributes array?
Thanks!

Here is the approach using URLSearchParams and going over each search param, parse and push to array of objects.
var sp = new URLSearchParams(
"myLocalSite/?attributes%5B0%5D%5Bname%5D=customer_property_number&attributes%5B0%5D%5Bop%5D=equal&attributes%5B0%5D%5Bvalue%5D=12&attributes%5B1%5D%5Bname%5D=feedback_tags&attributes%5B1%5D%5Bop%5D=in&attributes%5B1%5D%5Bvalue%5D=test+1%2Cwww"
);
var attributes = [];
for (entry of sp) {
const [attr, value] = entry;
const [index, key] = attr
.split("[")
.filter(x => x.includes("]"))
.map(x => x.slice(0, -1));
if (!attributes[Number(index)]) {
attributes[Number(index)] = {};
}
attributes[Number(index)][key] = value;
}
console.log(attributes);

Related

Merge two Object based on Object one value with Object two key

Want to merge object key values with another object value.
Suppose results object key should match with headers object key_name match because header should be CamelCase.
I have headers object is:
let headers = [
{ key_name: 'pid', header_value: 'PID' },
{
key_name: 'card_no',
header_value: 'Card Number'
},
{
key_name: 'trans_id',
header_value: 'Transaction ID'
},
{
key_name: 'card_name',
header_value: 'Card Name'
}
]
results Object is:
let results = let results = [
{
pid: '1234567890',
card_no: '546.......3742',
trans_id: '2019124453159',
card_name: 'Mastercard',
code: '$'
},
{
pid: '1234567890',
card_no: '546.......3742',
trans_id: '2019120534555',
card_name: 'Visa',
code: 'INR'
}
]
Header object key_name matching values need to filter in final results Object like below.
expected results is:
let results = [
{
PID: '1234567890',
Card Number: '546.......3742',
Transaction ID: '2019124453159',
Card Name: 'Mastercard'
},
{
PID: '1234567890',
Card Number: '546.......3742',
Transaction ID: '2019120534555',
Card Name: 'Visa'
}
]
I tried with below script its returning all values only:
for (let index = 0; index < results.length; index++) {
for (let i = 0; i < headers.length; i++) {
console.log(results [index][header[i].key_name])
}
}
I would suggest turning the first object into a map, so you have faster look-up. Then turn your objects into key/value pairs with Object.entries, perform the mapping and the filtering, and then turn those pairs back to an object with Object.fromEntries
let headers = [{ key_name: 'pid', header_value: 'PID' },{key_name: 'card_no',header_value: 'Card Number'},{key_name: 'trans_id',header_value: 'Transaction ID'},{key_name: 'card_name',header_value: 'Card Name'}];
// Convert to map:
let map = new Map(headers.map(({key_name, header_value}) => [key_name, header_value]));
let arr = [{pid: '1234567890',card_no: '546.......3742',trans_id: '2019124453159',card_name: 'Mastercard',code: '$'},{pid: '1234567890', card_no: '546.......3742',trans_id: '2019120534555',card_name: 'Visa',code: 'INR'}];
// Use map to make transition
let result = arr.map(obj =>
Object.fromEntries(Object.entries(obj).map(([key, value]) =>
map.has(key) && [map.get(key), value]
).filter(Boolean))
);
console.log(result);
You could look into the Object.keys(..) of the results array so you can map the old key values to the new ones.
You could use something like this:
const mappedHeaders = results.map((r) => {
const keys = Object.keys(r);
let newObj = {};
for (const key of keys) {
const newHeader = headers.find((h) => h.key_name === key);
if (newHeader) newObj[newHeader.header_value] = r[key];
}
return newObj;
});
You may need to check if the mapping exists and handle such cases to avoid errors.

Modify JavaScript code to use higher order functions

My below code is working fine and gives the correct desired output. But I am trying to use map, filter etc. instead of for loop. Lodash map and filter also works.
var arr = [
{"comp_id":1, desc: 'from comp1', updated: true},
{
"comp_id":2, desc: 'from comp2', updated: false}
];
var complaint_sources = [
{"comp_id":2,"consumer_source":"Hotline In","description_option":"English"},
{"comp_id":1,"consumer_source":"Online","description_option":"Other"},
{"comp_id":1,"consumer_source":"Email","description_option":null},
{"comp_id":2,"consumer_source":"Email","description_option":null}]
for(let i =0 ;i<arr.length;i++) {
let x=[];
for(let j=0;j<complaint_sources.length;j++){
if(arr[i].comp_id === complaint_sources[j].comp_id){
x.push(complaint_sources[j]);
arr[i].comp_src = x;
}
}
}
console.log(arr);
Basically I am looping through arr array and inside that looping through the complaint_sources array and when the comp_id matches I am modifying the arr array and adding a comp_src property to the object of arr array. This comp_src property will be an array of complaint_sources matched by comp_id.
this will work:
var arr = [
{"comp_id":1, desc: 'from comp1', updated: true},
{"comp_id":2, desc: 'from comp2', updated: false}
];
var complaint_sources = [
{"comp_id":2,"consumer_source":"Hotline In","description_option":"English"},
{"comp_id":1,"consumer_source":"Online","description_option":"Other"},
{"comp_id":1,"consumer_source":"Email","description_option":null},
{"comp_id":2,"consumer_source":"Email","description_option":null}
];
const grouped_sources = complaint_sources.reduce((acc, value) => {
(acc[value.comp_id] = acc[value.comp_id] || []).push(value);
return acc;
}, {})
const data = arr.map((comp) => ({
...comp,
comp_src: grouped_sources[comp.comp_id]
}));
console.log(data);

how to convert nested array of objects to object of array

I have got array of nested array of objects .
const data = [ {group: [{label:"1"}]}, {topGroup: [{label:"2"}]} ]
I want to convert array to this format of objects and I want to get this output
let permission ={
group:["1"],
topGroup:["2"]
}
How can I do this ?
const data = [ {group: [{label:"1"}]}, {topGroup: [{label:"2"}]} ]
const converted = data.reduce((a,b) => {
const onlyKey = Object.keys(b)[0];
a[onlyKey] = b[onlyKey].map(i => i.label);
return a;
}, {})
console.log(converted)
const data = [ {group: [{label:"1"}]}, {topGroup: [{label:"2"}]} ]
let permission = {};
data.forEach(val =>{
for(prop in val){
permission[prop] = [val[prop][0]["label"]]
}
})
console.log(permission)
Give this a upvote if this is what you want.
Assuming the data is going to have labels as in that format forever, you could use something like that
const data = [{"group":[{"label":"1"}]},{"topGroup":[{"label":"12"}]}];
// The dict variable under here is the second parameter of reduce that I passed it `{}`.
// The ind variable is the data at the index of the array.
var newData = data.reduce(function(dict, ind){
// You basically get the keys and the values and put them in place
// and return the last state to the reduce function.
dict[Object.keys(ind)] = Object.values(ind)[0][0]["label"];
return dict;
}, {})
console.log(newData)
Use destructuring and Object.fromEntries.
const data = [{ group: [{ label: "1" }] }, { topGroup: [{ label: "2" }] }];
const permission = Object.fromEntries(
data.map(item => {
const [[key, [obj]]] = Object.entries(item);
return [key, Object.values(obj)];
})
);
console.log(permission);

Get unique keys only from javascript array, where keys and value both are dynamic

This is my object-
[{"index":"style_bags","name":"24"},
{"index":"style_bags","name":"25"},
{"index":"style_bags","name":"26"},
{"index":"category_gear","name":"90"},
{"index":"category_gear","name":"98"},
{"index":"price","name":"400-"}]
This is expected -
[{"index":"style_bags","name":"26"},
{"index":"category_gear","name":"98"},
{"index":"price","name":"400-"}]
Requirement is to get last value and key pair from object in javascript.
As per asked from Certain Performance The way I reached here was through this code -
if(href.indexOf("&") >= 0){
var hrefSplit = href.split('&');
}
if(!(href.indexOf("&") >= 0)){
var hrefSplit = href.split('?');
var hrefSplit2 = hrefSplit[1].split('=');
}
params.push({ index: hrefSplit2[0], name: hrefSplit2[1]});
var i = 0;
jquery.each(params, function( index, value ) {
var key = value.index;
if(hrefSplit2[0] == key){
i++;
}
});
valueGet.push({ index: hrefSplit2[0], name: hrefSplit2[1]});
I am not a javascript pro, so was kind of blank on how to proceed further.
I will make a temp object storing the last found values and then create the resulting array.
let tempObj = {}
let srcArray = [
{"index":"style_bags","name":"24"},
{"index":"style_bags","name":"25"},
{"index":"style_bags","name":"26"},
{"index":"category_gear","name":"90"},
{"index":"category_gear","name":"98"},
{"index":"price","name":"400-"}];
for (let item of srcArray) {
tempObj[item.index] = item.name
}
let result = Object.keys(tempObj).map(index => {
return {
index,
name: tempObj[index]
}
});
console.log(result)
You can use reduce to create an object and then Object.values to get array of values. It will get last object based on index property.
const data = [{"index":"style_bags","name":"24"}, {"index":"style_bags","name":"25"}, {"index":"style_bags","name":"26"}, {"index":"category_gear","name":"90"}, {"index":"category_gear","name":"98"}, {"index":"price","name":"400-"}]
const result = data.reduce((r, e) => Object.assign(r, {[e.index]: e}), {})
console.log(Object.values(result))
You could use a Map and collect the last object with the same index property.
var array = [{ index: "style_bags", name: "24" }, { index: "style_bags", name: "25" }, { index: "style_bags", name: "26" }, { index: "category_gear", name: "90" }, { index: "category_gear", name: "98" }, { index: "price", name: "400-" }],
result = [...new Map(array.map(o => [o.index, o])).values()];
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You inspired me to update my javascript linq library to support .last(). So, using this library, you could:
var list = [{"index":"style_bags","name":"24"},
{"index":"style_bags","name":"25"},
{"index":"style_bags","name":"26"},
{"index":"category_gear","name":"90"},
{"index":"category_gear","name":"98"},
{"index":"price","name":"400-"}];
var filtered = loq(list).groupBy(x => x.index).select(g => g.last());
console.log(filtered.toArray());
<script src="https://cdn.rawgit.com/biggyspender/loq/cb4e5cb4/lib/loq.min.js"></script>

Javascript using filter/includes on an array of objects

What is the best way to filter out data that exists within an object?
I was able to do use the below code when data was just an array of values but now I need to filter out any data where the item.QID exists in my array of objects.
Data Obj:
var data = [{
QID: 'ABC123',
Name: 'Joe'
},
{
QID: 'DEF456',
Name: 'Bob
}]
Snippet:
// I don't want to include data if this QID is in my object
this.employees = emp.filter(item =>!this.data.includes(item.QID));
From what I understand, includes only works on an array so I need to treat all of the QID values in my object as an array.
Desired Outcome: (assuming item.QID = ABC123)
this.employees = emp.filter(item =>!this.data.includes('ABC123'));
Result:
var data = [{
QID: 'DEF456',
Name: 'Bob'
}]
UPDATE:
Apologies, I left some things a little unclear trying to only include the necessary stuff.
// People Search
this.peopleSearchSub = this.typeahead
.distinctUntilChanged()
.debounceTime(200)
.switchMap(term => this._mapsService.loadEmployees(term))
.subscribe(emp => {
// Exclude all of the current owners
this.employees = emp.filter((item) => item.QID !== this.data.QID);
}, (err) => {
this.employees = [];
});
The above code is what I am working with. data is an object of users I want to exclude from my type-ahead results by filtering them out.
The question is a little ambiguous, but my understanding (correct me if I'm wrong), is that you want to remove all items from a list emp that have the same QID as any item in another list data?
If that's the case, try:
this.employees = emp.filter(item => !this.data.some(d => d.QID === item.QID))
some is an array method that returns true if it's callback is true for any of the arrays elements. So in this case, some(d => d.QID === item.QID) would be true if ANY of the elements of the list data have the same QID as item.
Try Object#hasOwnProperty()
this.employees = emp.filter(item =>item.hasOwnProperty('QID'));
You can use a for ... in to loop through and filter out what you want:
const data = [{
QID: 'ABC123',
Name: 'Joe'
},
{
QID: 'DEF456',
Name: 'Bob'
}]
let newData = [];
let filterValue = 'ABC123';
for (let value in data) {
if (data[value].QID !== filterValue) {
newData.push(data[value]);
}
}
newData will be your new filtered array in this case
You can use an es6 .filter for that. I also added a couple of elements showing the filtered list and an input to allow changing of the filtered value. This list will update on the click of the button.
const data = [{
QID: 'ABC123',
Name: 'Joe'
},
{
QID: 'DEF456',
Name: 'Bob'
}]
displayData(data);
function displayData(arr) {
let str = '';
document.getElementById('filterList').innerHTML = '';
arr.forEach((i) => { str += "<li>" + i.QID + ": " + i.Name + "</li>"})
document.getElementById('filterList').innerHTML = str;
}
function filterData() {
let filterValue = document.getElementById('filterInput').value;
filterText (filterValue);
}
function filterText (filterValue) {
let newArr = data.filter((n) => n.QID !== filterValue);
displayData(newArr)
}
<input id="filterInput" type="text" value="ABC123" />
<button type ="button" onclick="filterData()">Filter</button>
<hr/>
<ul id="filterList"><ul>

Categories