I'm trying to create an object from a string array.
I've this string array :
let BaseArray = ['origin/develop', 'origin/master', 'toto/branch', 'tata/hello', 'tata/world'];
and I would like to have an object like that :
{
origin : ['develop', 'master'],
toto : ['branch'],
tata : ['hello', 'world']
}
So for the moment, I did this :
let Obj = {};
let RemoteObj = {};
for (let CurrentIndex = 0; CurrentIndex < BaseArray.length; CurrentIndex++) {
let Splits = BaseArray[CurrentIndex].split('/');
if (Splits[0] && Splits[1]) {
Obj[Splits[0]] = Splits[1].trim();
}
if (this.isObjectEmpty(RemoteObj)) {
RemoteObj = Obj;
} else {
RemoteObj = this.mergeObjects(RemoteObj, Obj);
}
console.log(RemoteObj);
}
And my utils functions are :
mergeObjects(...objs) {
let Result = {}, Obj;
for (let Ind = 0, IndLen = objs.length; Ind < IndLen; Ind++) {
Obj = objs[Ind];
for (let Prop in Obj) {
if (Obj.hasOwnProperty(Prop)) {
if (!Result.hasOwnProperty(Prop)) {
Result[Prop] = [];
}
Result[Prop].push(Obj[Prop]);
}
}
}
return Result;
}
isObjectEmpty(Obj) {
for (let Key in Obj) {
if (Obj.hasOwnProperty(Key)) {
return false;
}
return true;
}
}
I'm sure there is a better solution to do it but I can't do it.
So I'm open to any help !
Thanks by advance !
You can use Array.reduce() to create the object by splitting each string to the key and value, assigning an empty array to the key if it doesn't exist, and pushing the value to the array:
const BaseArray = ['origin/develop', 'origin/master', 'toto/branch', 'tata/hello', 'tata/world'];
const result = BaseArray.reduce((r, str) => {
const [key, value] = str.split('/');
if(!r[key]) r[key] = [];
r[key].push(value);
return r;
}, {});
console.log(result);
You can use Array.reduce() for this approach. On each iteration of reduce you can split your string by / and use the first element as a key on the new object and then put the second element on the array associated with that key:
let BaseArray = ['origin/develop', 'origin/master', 'toto/branch', 'tata/hello', 'tata/world'];
let res = BaseArray.reduce((acc, curr) =>
{
let [k, v] = curr.split("/");
(acc[k] = acc[k] || []).push(v);
return acc;
}, {});
console.log(res);
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}
You can use split and reduce
let BaseArray = ['origin/develop', 'origin/master', 'toto/branch', 'tata/hello', 'tata/world'];
let op = BaseArray.reduce((op, inp) => {
let [key, value] = inp.split('/')
op[key] = op[key] || []
op[key].push(value)
return op
},{})
console.log(op)
You can use the reduce method to build your object.
let baseArray = ['origin/develop', 'origin/master', 'toto/branch', 'tata/hello', 'tata/world'];
let baseobj = baseArray.reduce((acc, curr) => {
let items = curr.split('/');
let key = items[0];
let value = items[1];
if(acc[key] === undefined) {
acc[key] = [value]
} else {
acc[key] = [...acc[key], value];
}
return acc;
}, {});
console.log(baseobj);
You can use reduce & split the string which will give an array. Then use the element at index 0 of the array to create the object key. And push rest of the value to the array
let BaseArray = ['origin/develop', 'origin/kit/sub', 'origin/master', 'toto/branch', 'tata/hello', 'tata/world'];
let newArray = BaseArray.reduce(function(acc, curr) {
let splitCurr = curr.split('/');
if (!acc[splitCurr[0]]) {
acc[splitCurr[0]] = []
}
for (let i = 1; i < splitCurr.length; i++) {
acc[splitCurr[0]].push(splitCurr[i])
}
return acc;
}, {});
console.log(newArray)
Related
I am trying to remove duplicate JSON Objects from the array in ServiceNow.
Tried below code but it does not remove the duplicate. I want to compare both name & city.
var arr1 = '[{"name":"Pune","city":"India"},{"name":"Pune","city":"India"}]';
var splitlen = JSON.parse(arr1);
alert(splitlen.length);
var uniqueArray = [];
var uniqueJson = {};
for(i=0;i<splitlen.length;i++)
{
if(uniqueArray.indexOf(splitlen[i].name)==-1)
{
uniqueArray.push(splitlen[i]);
}
}
alert(JSON.stringify(uniqueArray));
Expected output :
[{"name":"Pune","city":"India"}]
uniqueArray.indexOf doesn't work because you're comparing objects against strings (splitlen[i].name). Try to use .find() instead:
var arr1 = '[{"name":"Pune","city":"India"},{"name":"Pune","city":"India"}]';
var splitlen = JSON.parse(arr1);
var uniqueArray = [];
var uniqueJson = {};
for(i=0;i<splitlen.length;i++)
{
if(!uniqueArray.find(x => x.name === splitlen[i].name))
{
uniqueArray.push(splitlen[i]);
}
}
console.log(uniqueArray);
or
var arr1 = '[{"name":"Pune","city":"India"},{"name":"Pune","city":"India"}]';
var splitlen = JSON.parse(arr1);
function compare(x){
return x.name === splitlen[i].name;
}
var uniqueArray = [];
var uniqueJson = {};
for(i=0;i<splitlen.length;i++)
{
if(!uniqueArray.find(compare))
{
uniqueArray.push(splitlen[i]);
}
}
console.log(uniqueArray);
you can try this. Also one more thing your array declaration is not right, remove single quotes from array.
var arr1 = [{"name":"Pune","city":"India"},{"name":"Pune","city":"India"}];
function getUniqueListByKey(arr, key) {
return [...new Map(arr.map(item => [item[key], item])).values()]
}
var arr2 = getUniqueListByKey(arr1, "name")
console.log(arr2);
Please try the following example
const arr1 = '[{"name":"Pune","city":"India"},{"name":"Pune","city":"India"}]';
const splitlen = JSON.parse(arr1);
const output = splitlen.reduce((previousValue, currentValue) => {
const { name, city } = currentValue;
const index = previousValue.findIndex(
(entry) => entry.name === name && entry.city === city
);
if (index === -1) {
return [...previousValue, currentValue];
}
return previousValue;
}, []);
console.log(output);
See
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex
Put the records in a hashset. If there is collision in the hashset, there is duplicate. This approach is O(n) while comparing all pairs is $O(n^2)$.
I'm trying to get an answer, here's my idea:
Create a function to compare two objects then create a function to get the unique value
function isEquals(obj1, obj2) {
const aProps = Object.getOwnPropertyNames(obj1);
const bProps = Object.getOwnPropertyNames(obj2);
if (aProps.length !== bProps.length) {
return false;
}
for (let j = 0; j < aProps.length; j++) {
const propName = aProps[j];
if (JSON.stringify(obj1[propName]) !== JSON.stringify(obj2[propName])) {
return false;
}
} return true;
}
function getUnique(arr) {
var uniqueArray = [];
for (var item of arr) {
const uniqueItems = arr.filter(i => isEquals(item, i));
if (uniqueItems.length !== 0) {
uniqueArray.push(Object.assign({}, uniqueItems.shift()));
}
arr = arr.filter(i => !isEquals(item, i));
}
return uniqueArray;
}
Hope it helps!
I'm trying to create an algorithm to find duplicate values in a list and return their respective indexes, but the script only returns the correct value, when I have 2 equal elements:
array = [1,2,0,5,0]
result -> (2) [2,4]
Like the example below:
array = [0,0,2,7,0];
result -> (6) [0, 1, 0, 1, 0, 4]
The expected result would be [0,1,4]
Current code:
const numbers = [1,2,0,5,0];
const checkATie = avgList => {
let averages, tie, n_loop, currentAverage;
averages = [... avgList];
tie = [];
n_loop = 0;
for(let n = 0; n <= averages.length; n++) {
currentAverage = parseInt(averages.shift());
n_loop++
for(let avg of averages) {
if(avg === currentAverage) {
tie.push(numbers.indexOf(avg),numbers.indexOf(avg,n_loop))
};
};
};
return tie;
}
console.log(checkATie(numbers));
if possible I would like to know some way to make this code more concise and simple
Use a Set
return [...new Set(tie)]
const numbers1 = [1,2,0,5,0];
const numbers2 = [0,0,2,7,0];
const checkATie = avgList => {
let averages, tie, n_loop, currentAverage;
averages = [... avgList];
tie = [];
n_loop = 0;
for(let n = 0; n <= averages.length; n++) {
currentAverage = parseInt(averages.shift());
n_loop++
for(let avg of averages) {
if(avg === currentAverage) {
tie.push(avgList.indexOf(avg),avgList.indexOf(avg,n_loop))
};
};
};
return [...new Set(tie)]
}
console.log(checkATie(numbers1));
console.log(checkATie(numbers2));
I hope this help you.you can use foreach function to check each item of array
var array = [0,0,2,7,0];
var result = [] ;
array.forEach((item , index)=>{
if(array.findIndex((el , i )=> item === el && index !== i ) > -1 ){
result.push(index)
}
})
console.log(result);
//duplicate entries as an object
checkDuplicateEntries = (array) => {
const duplicates = {};
for (let i = 0; i < array.length; i++) {
if (duplicates.hasOwnProperty(array[i])) {
duplicates[array[i]].push(i);
} else if (array.lastIndexOf(array[i]) !== i) {
duplicates[array[i]] = [i];
}
}
console.log(duplicates);
}
checkDuplicateEntries([1,2,0,5,0]);
// hope this will help
Create a lookup object with value and their indexes and then filter all the values which occurred more than once and then merge all indexes and generate a new array.
const array = [1, 2, 0, 5, 0, 1, 0, 2],
result = Object.values(array.reduce((r, v, i) => {
r[v] = r[v] || [];
r[v].push(i);
return r;
}, {}))
.filter((indexes) => indexes.length > 1)
.flatMap(x => x);
console.log(result);
I need to treat array values as props of object. For example:
let arr = ['masa_icerik', 'urunler', 0, 'urun_adet'];
let obj = {
"_id": "5c13bd566704aa5e372dddcf",
"masa_id": 3,
"masa_numara": 3,
"masa_magaza": 1,
"masa_icon": "kola",
"masa_adi": "salon 3",
"masa_durum": 1,
"masa_icerik": {
"adisyon": "J1554745811908",
"urunler": [{
"urun_adet": 14,
"urun_fiyat": 3,
"urun_id": "5c16686b93d7b79ae6367864",
"urun_odenen": 0
}, {
"urun_adet": 1,
"urun_fiyat": 5,
"urun_id": "5c16686b93d7b79ae6367865",
"urun_odenen": 0
}]
},
"masa_acilis": "2019-04-08T17:50:12.052Z",
"masa_acan": "5c1eda01d1f4773110dd6ada"
};
I have an array and an object like above and I want to do something like this:
let res;
arr.forEach(elem => {
res = obj[elem];
});
and after that I need to get something like :
obj['masa_icerik']['urunler'][0]['urun_adet']
The number of the values is dynamic from server. Thats why i need something like this. Is there any way to do that? I need to change that property and return the changed obj.
You can use forEach loop to loop thru the array and store it to a temp variable. If all elements exist, it will change the value.
let arr = ['a', 'b', 'c'];
let obj = {'a':{'b':{'c':1}}};
let newValue = "NEW VALUE";
let temp = obj;
arr.forEach((o, i) => {
if (i < arr.length - 1) temp = temp[o] || null;
else if (temp !== null && typeof temp === "object" ) temp[o] = newValue;
});
console.log(obj);
If there are multiple multiple object properties missing in the last part of the array.
let arr = ['a', 'b', 'c', 'd'];
let obj = {'a': {'b': {}}};
let newValue = "NEW VALUE";
let temp = obj;
arr.forEach((o, i) => {
if (i < arr.length - 1) {
if (!temp[o]) temp[o] = {[arr[i + 1]]: {}};
temp = temp[o];
} else if (temp !== null && typeof temp === "object") temp[o] = newValue;
});
console.log(obj);
You can use references
Here idea is
Initialize val with object reference
Loop through array and keep setting new reference to val
let arr = ['a','b','c'];
let obj = {'a':{'b':{'c':1}}};
let getMeValue = (arr) => {
let val=obj;
arr.forEach(e => val = val && val[e] )
return val
}
console.log(getMeValue(arr))
console.log(getMeValue([1,2,3]))
UPDATE: I want to change values
let arr = ['a','b','c'];
let obj = {'a':{'b':{'c':1}}};
let getMeValue = (arr) => {
let val = obj
arr.forEach((e,i) => {
if(i === arr.length-1 && val){
val[e] = 5
}
else {
val = val && val[e]
}
})
return obj
}
console.log(getMeValue(arr))
I am not fully understanding where you are getting the new values from but I think this will get you on the right track.
let newObj = {};
arr.map(each => {
newObj[each] = "new value";
})
console.log(newObj);
I'm not sure about your requirment here, I guess you want the below:
let func = (arr, value)=>{
r = {};
r[arr[arr.length-1]] = value;
for(let i = arr.length-2; i>=0; i--){
obj = {};
obj[arr[i]] = r;
r = obj;
}
return r;
}
console.log(func(['a', 'b', 'c'], 1));
I am trying to convert a string into a delimited object key but I need some assistance on how to iterate over the length of the array and join accordingly.
SET('my.delimited.string.of.unknown.length')
const SET = key => (state, val) => {
if(key.indexOf('.') !== -1) {
let array = key.split(".")
for (var i = 0; i < array.length; i++) {
// what should I do here?
}
// desired output based on array length
// state[ array[0] ][ array[1] ] = val
// state.my.delimited.string.of.unknown.length = val
}
}
One of those very rare usecases for reduce:
const keys = key.split(".");
const prop = keys.pop();
keys.reduce((acc, key) => acc[key], state)[prop] = val;
For sure that could also be done with a for loop:
let array = key.split("."), acc = state;
for (var i = 0; i < array.length - 1; i++) {
acc = acc[ array[i] ];
}
acc[ array.pop() ] = val;
For setting a value, you could split the path and reduce the path by walking the given object. If no object exist, create a new property with the name. Later assign the value.
function setValue(object, path, value) {
var keys = path.split('.'),
last = keys.pop();
keys.reduce((o, k) => o[k] = o[k] || {}, object)[last] = value;
}
var test = {};
setValue(test, "first.deep.property", 1);
setValue(test, "and.another.deep.property", 20);
console.log(test);
You could also do this with a single Array.reduce:
const makeObject = (arr, val, obj={}) => {
arr.split('.').reduce((r,c,i,a) => r[c] = i == a.length-1 ? val : {}, obj)
return obj
}
console.log(makeObject("first.deep.property", 1))
console.log(makeObject("and.another.deep.property", 20))
Actually my function calculate the sum of all same keys in each object
const arr = [{id:1, "my color":1,"my fruit":4},{id:2,"my color":2,"my fruit":4}];
const res = arr.reduce((a, { id, ...rest }) => {
Object.entries(rest).forEach(([key, val]) => {
a[key] = (a[key] || 0) + val;
});
return a;
}, {});
result is >> [{"my color":3,"my fruit":8}
I'd like to get their percent (value/sum of values) and not instead their sum, like this
{ "my color": 27, "my fruit": 73 }
Try following
var obj = {"my color":3,"my fruit":8};
var total = Object.values(obj).reduce((a,c) => a+c, 0);
Object.keys(obj).forEach(k => obj[k] = Math.round(obj[k]*100/total));
console.log(obj);
Well just sum up all values first, then divide each entry by that:
// Sum up all properties with same key
const sum = { };
for(const entry of array) {
for(const [key, value] of Object.entries(entry)) {
sum[key] = (sum[key] || 0) + value;
}
}
// Map the array to an array of percentages
const percentage = array.map(entry => {
const result = {};
for(const [key, value] of Object.entries(entry)) {
result[key] = value / sum[key] * 100;
}
return result;
});