how to convert multi element object to one element object - javascript

I have object like this
[
{ A: '1' },
{ B: '2' },
{ C: '3' },
]
I want convert to like this
{
A: '1',
B: '2',
C: '3',
}
what is the best way to do it

Object.assign with spread syntax
let arr = [
{ A: '1' },
{ B: '2' },
{ C: '3' },
]
console.log(Object.assign(...arr));

let arr = [
{ A: '1' },
{ B: '2' },
{ C: '3' },
]
let output = {}
arr.map((obj) => {
output = {...output, ...obj}
})
console.log(output)

Object.assign and spread operator will do the trick :
let arrObject = [
{ A: "1" },
{ B: "2" },
{ C: "3" }
];
Object.assign(target, ...sources)
let obj = Object.assign({}, ...arrObject);
console.log(obj) => obj = { A: '1', B: '2', C: '3' }

Related

reducing nested object key value inside an an array

i have the following arrays
array1 = [
{a:{key:1 , value: 10} , b:{key:1 , value:12} , c:{key:1 , value: 5} , d:{key:1 , value:2}},
{a:{key:2 , value: 10} , b:{key:2 , value:12} , c:{key:2 , value: 5} , d:{key:2 , value:2}},
{a:{key:3 , value: 10} , b:{key:3 , value:12} , c:{key:3 , value: 5} , d:{key:3 , value:2}},
]
array2 = [
{a:{key:1 , value: 10} , b:{key:1 , value:12} , c:{key:1 , value: 5} , d:{key:1 , value:2}},
{a:{key:2 , value: 10} , b:{key:2 , value:12} , c:{key:2 , value: 5} , d:{key:2 , value:2}},
{a:{key:4 , value: 10} , b:{key:4 , value:12} , c:{key:4 , value: 5} , d:{key:4 , value:2}},
]
reduced array based on key should look like this:
combinedArray= [
{a:{key:1 , value: 20} , b:{key:1 , value:24} , c:{key:1 , value: 10} , d:{key:1 , value:4}},
{a:{key:2 , value: 20} , b:{key:2 , value:24} , c:{key:2 , value: 10} , d:{key:2 , value:4}},
{a:{key:3 , value: 10} , b:{key:3 , value:12} , c:{key:3 , value: 5} , d:{key:3 , value:2}},
{a:{key:4 , value: 10} , b:{key:4 , value:12} , c:{key:4 , value: 5} , d:{key:4 , value:2}},
]
first i tried to merge the two arrays using const mergedArray = [...array1, ...array2]
now i want to check for key duplicates. for example, if there is key1 in both array1 and array2, remove the duplicates then combine the values of that key.
this is what i have tried but it is only iterating through a.key only:
function kdeAdder(param) {
const array = [param.a]
let tempHistory = [];
for(let x=0;x<array.length;x++){
array[x].forEach((item)=>{
let noMatch = true;
if(tempHistory.length > 0) {
tempHistory.forEach((tempItem, i)=>{
if(item.key === tempItem.key) {
tempHistory[i].value += item.value;
noMatch = !noMatch;
}
});
}
return (noMatch) ? tempHistory.push(item) : null;
});
}
return tempHistory;
}
kdeAdder(mergedArray);
As you confirmed the key inner property is commonly shared by the four "a", "b", "c", "d" objects in an outer object, the a.key value can be used to identify which outer objects should merge.
You could group all objects (irrespective of whether they occur in array1 or array2) by that a.key, and then aggregate objects that occur in the same group. Both of these actions can be accomplished with a reduce call:
const aggregate = (objects) =>
objects.reduce((x, y) => ({
a: { key: x.a.key, value: x.a.value + y.a.value },
b: { key: x.b.key, value: x.b.value + y.b.value },
c: { key: x.c.key, value: x.c.value + y.c.value },
d: { key: x.d.key, value: x.d.value + y.d.value },
}));
const merge = (array1, array2) =>
Object.values(array1.concat(array2).reduce((acc, obj) => {
(acc[obj.a.key] ??= []).push(obj);
return acc;
}, {})).map(aggregate);
const array1 = [
{a:{key:1 , value: 10} , b:{key:1 , value:12} , c:{key:1 , value: 5} , d:{key:1 , value:2}},
{a:{key:2 , value: 10} , b:{key:2 , value:12} , c:{key:2 , value: 5} , d:{key:2 , value:2}},
{a:{key:3 , value: 10} , b:{key:3 , value:12} , c:{key:3 , value: 5} , d:{key:3 , value:2}},
];
const array2 = [
{a:{key:1 , value: 10} , b:{key:1 , value:12} , c:{key:1 , value: 5} , d:{key:1 , value:2}},
{a:{key:2 , value: 10} , b:{key:2 , value:12} , c:{key:2 , value: 5} , d:{key:2 , value:2}},
{a:{key:4 , value: 10} , b:{key:4 , value:12} , c:{key:4 , value: 5} , d:{key:4 , value:2}},
]
console.log(merge(array1, array2));
You can first reduce the output to a single object since its a sort of accumulation of numbers, and then get the format you want as the second step.
const array1 = [ { a: { key: 1, value: 10 }, b: { key: 1, value: 12 }, c: { key: 1, value: 5 }, d: { key: 1, value: 2 }, }, { a: { key: 2, value: 10 }, b: { key: 2, value: 12 }, c: { key: 2, value: 5 }, d: { key: 2, value: 2 }, }, { a: { key: 3, value: 10 }, b: { key: 3, value: 12 }, c: { key: 3, value: 5 }, d: { key: 3, value: 2 }, }, ]; const array2 = [ { a: { key: 1, value: 10 }, b: { key: 1, value: 12 }, c: { key: 1, value: 5 }, d: { key: 1, value: 2 }, }, { a: { key: 2, value: 10 }, b: { key: 2, value: 12 }, c: { key: 2, value: 5 }, d: { key: 2, value: 2 }, }, { a: { key: 4, value: 10 }, b: { key: 4, value: 12 }, c: { key: 4, value: 5 }, d: { key: 4, value: 2 }, }, ];
const mergedArray = [...array1, ...array2];
const keys = []
const reducedOutput = mergedArray.reduce((prev, curr) => {
Object.entries(curr).forEach(([mainKey, { key, value }]) => {
// mainKey is a, b, c, d in your case
if (!prev[mainKey]) {
prev[mainKey] = {};
}
// key is 1, 2, 3, 4 in your case
if (!keys.includes(key)) {
keys.push(key)
}
prev[mainKey][key] = prev[mainKey][key]
? prev[mainKey][key] + value
: value;
});
return prev;
}, {});
const output = keys.map(key => {
const obj = {}
Object.entries(reducedOutput).forEach(([k, v]) => {
obj[k] = {key, value: v[key]}
})
return obj
})
console.log(output)
This will work with any other keys for a, b, c, d keys and 1, 2, 3, 4 keys you have used in two levels.
Using Object.entries(), Array.prototype.reduce(), Array.prototype.forEach(), and Array.prototype.map()
The following provided code implements an approach which tries to find a balance in between 1st being agnostic to any array item's current and future structure except for both property names, key and value, of any array item's second level structure and 2nd how to handle the merger of other unknown second level data.
Therefore the general approach creates an object based lookup from the shorter sourceList where each item gets referred to via the value of its second level key property, whereas the longer targetList will be reduced in order to create the final result of merged items from both arrays.
Since approach and implementation are unaware of an items first level structure, one has to reduce again all of a currently processed item's entries. For each of a target item's unknown entry one can rely on such an entry's 2nd level properties, key and value. From all the available data, either known or unknown, one can aggregate the common merger of both the source- and the target-item; their values will be totaled and both of their unknown rest data will be merged by spread syntax, where the latter is the approach's trade off/compromise.
function aggregateFirstValueKeyBasedLookup(lookup, item) {
lookup[Object.values(item)[0]?.key ?? ''] = item;
return lookup;
}
function createKeyBasedValueMergerFromSourceLookup(
{ lookup = {}, result = [] }, targetItem, idx, arr,
) {
let currentLookupKey;
result.push(Object
.entries(targetItem)
.reduce((merger, [
targetEntryKey, {
key, value: targetEntryValue = 0, ...targetEntryRest
}
]) => {
currentLookupKey = key;
const sourceItem = lookup[key] ?? {};
const {
value: sourceEntryValue = 0, ...sourceEntryRest
} = sourceItem[targetEntryKey] ?? {};
return Object.assign(merger, {
[ targetEntryKey ]: {
key,
value: (targetEntryValue + sourceEntryValue),
...targetEntryRest,
...sourceEntryRest,
},
});
}, {})
);
// delete already processed source-items from lookup.
Reflect.deleteProperty(lookup, currentLookupKey);
if (idx >= arr.length - 1) {
// finalize the result by ...
result.push(
// ...pushing all of the lookup's
// unprocessed source-items.
...[...Object.values(lookup)]
);
}
return { lookup, result };
}
const array1 = [{
a: { key: 1, value: 10 }, b: { key: 1, value: 12 }, c: { key: 1, value: 5 }, d: { key: 1, value: 2 }
}, {
a: { key: 2, value: 10 }, b: { key: 2, value: 12 }, c: { key: 2, value: 5 }, d: { key: 2, value: 2 }
}, {
a: { key: 3, value: 10 }, b: { key: 3, value: 12 }, c: { key: 3, value: 5 }, d: { key: 3, value: 2 }
}];
const array2 = [{
a: { key: 1, value: 10 }, b: { key: 1, value: 12 }, c: { key: 1, value: 5 }, d: { key: 1, value: 2 }
}, {
a: { key: 2, value: 10 }, b: { key: 2, value: 12 }, c: { key: 2, value: 5 }, d: { key: 2, value: 2 }
}, {
a: { key: 4, value: 10 }, b: { key: 4, value: 12 }, c: { key: 4, value: 5 }, d: { key: 4, value: 2 }
}];
const [ targetList, sourceList ]
= [array1, array2].sort((a, b) => b.length - a.length);
const sourceLookup = sourceList
.reduce(aggregateFirstValueKeyBasedLookup, Object.create(null));
console.log({ sourceLookup });
const { result: mergedItemList } = targetList
.reduce(createKeyBasedValueMergerFromSourceLookup, {
lookup: sourceLookup, result: [],
});
console.log({ mergedItemList });
// - changed item structure which keeps
// just the most necessary pattern.
const newItemStructureList1 = [{
quick: { key: 'foo', value: 33, biz: 'biz' },
brown: { key: 'foo', value: 22, baz: 'baz' },
fox: { key: 'foo', value: 11, buzz: 'buzz' },
}, {
quick: { key: 'bar', value: 11, baz: 'baz' },
brown: { key: 'bar', value: 33, biz: 'biz' },
fox: { key: 'bar', value: 22, booz: 'booz' },
}, {
quick: { key: 'baz', value: 22, baz: 'baz' },
brown: { key: 'baz', value: 11, biz: 'biz' },
fox: { key: 'baz', value: 33, booz: 'booz' },
}];
const newItemStructureList2 = [{
brown: { key: 'foo', value: 11, baz: 'baz' },
fox: { key: 'foo', value: 33, booz: 'booz' },
quick: { key: 'foo', value: 22, baz: 'baz' },
}, {
fox: { key: 'baz', value: 33, buzz: 'buzz' },
quick: { key: 'baz', value: 11, biz: 'biz' },
brown: { key: 'baz', value: 33, baz: 'baz' },
}];
const [ target, source ]
= [newItemStructureList1, newItemStructureList2].sort((a, b) => b.length - a.length);
const lookup = source
.reduce(aggregateFirstValueKeyBasedLookup, Object.create(null));
console.log({ lookup });
const { result: mergedItems } = target
.reduce(createKeyBasedValueMergerFromSourceLookup, { lookup, result: [] });
console.log({ mergedItems });
.as-console-wrapper { min-height: 100%!important; top: 0; }
You could group with the key property and the outer property.
const
array1 = [{ a: { key: 1, value: 10 }, b: { key: 1, value: 12 }, c: { key: 1, value: 5 }, d: { key: 1, value: 2 } }, { a: { key: 2, value: 10 }, b: { key: 2, value: 12 }, c: { key: 2, value: 5 }, d: { key: 2, value: 2 } }, { a: { key: 3, value: 10 }, b: { key: 3, value: 12 }, c: { key: 3, value: 5 }, d: { key: 3, value: 2 } }],
array2 = [{ a: { key: 1, value: 10 }, b: { key: 1, value: 12 }, c: { key: 1, value: 5 }, d: { key: 1, value: 2 } }, { a: { key: 2, value: 10 }, b: { key: 2, value: 12 }, c: { key: 2, value: 5 }, d: { key: 2, value: 2 } }, { a: { key: 4, value: 10 }, b: { key: 4, value: 12 }, c: { key: 4, value: 5 }, d: { key: 4, value: 2 } }],
result = Object.values([...array1, ...array2].reduce((r, o) => {
Object.entries(o).forEach(([k, { key, value }]) => {
r[key] ??= {};
r[key][k] ??= { key, value: 0 };
r[key][k].value += value;
});
return r;
}, {}));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Sorting a Map with dates as the key (javascript)

I want to sort a Map in javascript.
The map looks like this:
0: { key: '2020-09-29', value: { foo: 1, bar: 2} },
1: { key: '2020-09-01', value: { foo: 3, bar: 4} },
2: { key: '2020-09-08', value: { foo: 5, bar: 6} }
and so on..
I can't find a solution for this, can someone give me a hint?
I already tried something like this:
days_map = new Map([...days_map].sort(function(key, value) { return new Date(key); }));
but it's not sorting the map.
Thanks
You could sort the array with the key with String#localeCompare.
let map = new Map([['2020-09-29', { foo: 1, bar: 2 }], ['2020-09-01', { foo: 3, bar: 4 }], ['2020-09-08', { foo: 5, bar: 6 }]]),
sorted = new Map(Array.from(map).sort(([a], [b]) => a.localeCompare(b)));
console.log([...map]);
console.log([...sorted]);
.as-console-wrapper { max-height: 100% !important; top: 0; }
var input = [{
key: '2020-09-29',
value: {
foo: 1,
bar: 2
}
},
{
key: '2020-09-01',
value: {
foo: 3,
bar: 4
}
},
{
key: '2020-09-08',
value: {
foo: 5,
bar: 6
}
}
]
input.sort((a, b) => {
const first = a.key
const second = b.key
return first > second ? 1 : (first < second ? -1 : 0)
});
console.log(input);

How to get the combination of array values from nested arrays in an array of objects

I have an array of objects with the following structure:
var varientSections = [
{
type: "frame",
values: ["black", "white", "wood"]
},
{
type: "finish",
values: ["matte", "glossy"]
}
];
I want to get the combination of the array values and create a new list with it. Right now, I am able to retrieve the combination from the nested array values using the method called getCombination(varientSections). However, I do not know how to create a new list with the following structure:
var results = [
{
attributes: [
{
type: "frame",
value: "black"
},
{
type: "finish",
value: "matte"
}
]
},
{
attributes: [
{
type: "frame",
value: "black"
},
{
type: "finish",
value: "glossy"
}
]
},
{
attributes: [
{
type: "frame",
value: "white"
},
{
type: "finish",
value: "matte"
}
]
},
{
attributes: [
{
type: "frame",
value: "white"
},
{
type: "finish",
value: "glossy"
}
]
},
{
attributes: [
{
type: "frame",
value: "wood"
},
{
type: "finish",
value: "matte"
}
]
},
{
attributes: [
{
type: "frame",
value: "wood"
},
{
type: "finish",
value: "glossy"
}
]
}
];
Below is my code:
function getCombinations(arr) {
if (arr.length === 0) {
return [[]];
}
let [current, ...rest] = arr;
let combinations = getCombinations(rest);
var result = current.values.reduce(
(accumulator, currentValue) => [
...accumulator,
...combinations.map(c => [currentValue, ...c])
],
[]
);
console.log("result is ");
console.log(result);
return result;
}
let varientCombinations = getCombinations(varientSections);
console.log(varientCombinations);
let updatedVarientDetails = [];
varientSections.forEach((varientSection, index) => {
let type = varientSection.type;
varientCombinations.forEach(combination => {
let obj = [
{
type: type,
value: combination[index]
},
];
updatedVarientDetails.push(obj);
});
});
console.log(updatedVarientDetails);
You could get the cartesian product and give it later the wanted style. The names and values are taken form the handed over object.
The algorithm takes all key/value pairs and has a stric view to the values, that means if an array is found or an object, hence w && typeof w === "object", the actual part is taken an used for adding additional key/value pairs.
For example a small object with two properties
{ a: 1, b: [2, 3] }
yields
[
{ a: 1, b: 2 },
{ a: 1, b: 3 }
]
A bit more advanced object, like
{ a: 1, b: { c: { d: [2, 3], e: [4, 5] } } }
yields the same structure as given
[
{
a: 1,
b: {
c: { d: 2, e: 4 }
}
},
{
a: 1,
b: {
c: { d: 2, e: 5 }
}
},
{
a: 1,
b: {
c: { d: 3, e: 4 }
}
},
{
a: 1,
b: {
c: { d: 3, e: 5 }
}
}
]
Thant means, from any found sub object the cartesian product is taken and combined with the actual values.
const
getCartesian = object => Object.entries(object).reduce(
(r, [key, value]) => {
let temp = [];
r.forEach(s =>
(Array.isArray(value) ? value : [value]).forEach(w =>
(w && typeof w === "object" ? getCartesian(w) : [w]).forEach(x =>
temp.push({ ...s, [key]: x })
)
)
);
return temp;
},
[{}]
),
data = [{ type: "frame", value: ["black", "white", "wood"] }, { type: "finish", value: ["matte", "glossy"] }],
result = getCartesian(data)
.map(o => ({ attributes: Object.assign([], o).map(({ ...o }) => o) }));
console.log(result);
console.log(getCartesian({ a: 1, b: { c: { d: [2, 3], e: [4, 5] } } }));
.as-console-wrapper { max-height: 100% !important; top: 0; }
You could simplify it to this:
var variantSections = [
{
type: "frame",
values: ["black", "white", "wood"]
},
{
type: "finish",
values: ["matte", "glossy"]
}
];
// iterate through each variantSection and create objects like {"type": "frame", "value": "black"}
var sections = variantSections.map(variant => {
return variant.values.map(val => ({type: variant.type, value: val}))
});
// then iterate through the two resulting arrays of objects, combining each into the attributes object you want
var results = [];
for (var i = 0; i < sections[0].length; i++) {
for (var j = 0; j < sections[1].length; j++) {
results.push({attributes: [sections[0][i], sections[1][j]]});
}
}
console.log(JSON.parse(JSON.stringify(results)));

Ramda GroupBy - How to group by any prop

given:
interface Dict {
[key: string]: any
}
const data: Dict[] = [
{ id: 'a' },
{ id: 'b', b: 'something' },
{ id: 'c', b: 'else' },
{ id: 'd', extra: 'hello world' },
{ id: 'e' },
];
where the keys of these Dict objects aren't specified...
How can I get this result?
const result = {
id: ['a', 'b', 'c', 'd', 'e'],
b: ['something', 'else'],
extra: ['hello world'],
// ... and any other possible key
}
You can flatten the object into a list of pairs, group it, and convert the pairs back to values:
const data = [
{ id: 'a' },
{ id: 'b', b: 'something' },
{ id: 'c', b: 'else' },
{ id: 'd', extra: 'hello world' },
{ id: 'e' },
];
let z = R.pipe(
R.chain(R.toPairs),
R.groupBy(R.head),
R.map(R.map(R.last))
)
console.log(z(data))
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>
Slight variation from Ori Drori answer:
(assuming that no properties in your objects are contained in arrays already)
const data = [
{ id: 'a' },
{ id: 'b', b: 'something' },
{ id: 'c', b: 'else' },
{ id: 'd', extra: 'hello world' },
{ id: 'e' }
];
const run = reduce(useWith(mergeWith(concat), [identity, map(of)]), {});
console.log(
run(data)
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.min.js"></script>
<script>const {reduce, useWith, mergeWith, concat, identity, map, of} = R;</script>
Use R.reduce with R.mergeWith and concat all items:
const { mergeWith, reduce } = R
const fn = reduce(mergeWith((a, b) => [].concat(a, b)), {})
const data = [
{ id: 'a' },
{ id: 'b', b: 'something' },
{ id: 'c', b: 'else' },
{ id: 'd', extra: 'hello world' },
{ id: 'e' },
];
const result = fn(data)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>
If you need the single value (extra) in array as well, map the items, and wrap with an array, just the values that are not an array already:
const { pipe, mergeWith, reduce, map, unless, is, of } = R
const fn = pipe(
reduce(mergeWith((a, b) => [].concat(a, b)), {}),
map(unless(is(Array), of))
)
const data = [
{ id: 'a' },
{ id: 'b', b: 'something' },
{ id: 'c', b: 'else' },
{ id: 'd', extra: 'hello world' },
{ id: 'e' },
];
const result = fn(data)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>

value has been overrite in nested forLoop issue

I am not sure what' wrong with my code, value has been override in the nested for-loop, please help me debug following code. var1 is an array that contains another array called list. Var2 is also an array, and each var2.data is equal to the var1. I tried to setup the list.id = var2.index of each var2.data, but for some reason that all the list.id inside of var2 are equal 2, seems like that value has been override. Please see below:
let var1 = [{
'name': 'name1',
'list': [{
id: 0,
a: "test1",
b: 'test2'
},
{
id: 0,
a: "aac",
b: 'test2'
},
{
id: 0,
a: "aad",
b: 'test2'
},
]
},
{
'name': 'name2',
'list': [{
id: 0,
a: "test1",
b: 'test2'
},
{
id: 0,
a: "aac",
b: 'test2'
},
{
id: 0,
a: "aad",
b: 'test2'
},
]
}
];
let var2 = [{
claim: 'claim1',
ifn: '1',
data: []
},
{
claim: 'claim2',
ifn: '2',
data: []
},
{
claim: 'claim3',
ifn: '3',
data: []
},
]
var2.forEach((item, i) => {
var1.forEach(list => {
list.list.forEach(val => {
val.id = i;
})
item.data = list;
})
})
console.log(var2)
I would like to have that each list.id equal the index of var2, like below, really not sure how to make this code work, please help~
var2 = [
{ claim:'claim1',ifn:'1',
data:
[{
'name':'name1',
'list':[
{id:0,a:"test1",b:'test2'},
{id:0,a:"aac",b:'test2'},
{id:0,a:"aad",b:'test2'},
]
},
{
'name':'name2',
'list':[
{id:0,a:"test1",b:'test2'},
{id:0,a:"aac",b:'test2'},
{id:0,a:"aad",b:'test2'},
]
}]
},
{ claim:'claim2',ifn:'2',
data:
[{
'name':'name1',
'list':[
{id:1,a:"test1",b:'test2'},
{id:1,a:"aac",b:'test2'},
{id:1,a:"aad",b:'test2'},
]
},
{
'name':'name2',
'list':[
{id:1,a:"test1",b:'test2'},
{id:1,a:"aac",b:'test2'},
{id:1,a:"aad",b:'test2'},
]
}]
},
{ claim:'claim3',ifn:'3',
data:[{
'name':'name1',
'list':[
{id:2,a:"test1",b:'test2'},
{id:2,a:"aac",b:'test2'},
{id:2,a:"aad",b:'test2'},
]
},
{
'name':'name2',
'list':[
{id:2,a:"test1",b:'test2'},
{id:2,a:"aac",b:'test2'},
{id:2,a:"aad",b:'test2'},
]
}]
}
]
From my understanding, you want every data value in your var2 to point to var1. The following loop will do that:
var2.forEach(item => item.data = var1);
However, because each item points to the same object, it means that if you change any data item inside var2, it will change all of them.
If you need the copies to be unique, you can make a new copy with something like this:
const getVar1 = () => [
{
'name': 'name1',
'list': [
{
id: 0,
a: "test1",
b: 'test2'
},
{
id: 0,
a: "aac",
b: 'test2'
},
{
id: 0,
a: "aad",
b: 'test2'
},
]
},
...
];
and then you can use it like so:
var2.forEach(item => item.data = getVar1())
Here you need create new copy. But desire result you can use this code -
for (var i = 0; i < var2.length; i++) {
var el = var2[i], arr = [];
for (var j = 0; j < var1.length; j++) {
var o = var1[j];
for (var k = 0; k < o.list.length; k++) {
var ob = o.list[k];
console.log(ob);
ob.id = i;
}
arr.push(o);
}
el.data = arr;
}

Categories

Resources