I Have this array:
[
{id: 6, deductionTypeId: 6,deductionTypeTitle:"TypeTitle1",deductionExchangeTypeId:3,deductionExchangeTypeTitle: "Exchange1" ,wageTitle:"wageTitle1"}
{id: 8, deductionTypeId: 6,deductionTypeTitle:"TypeTitle1",deductionExchangeTypeId: 3deductionExchangeTypeTitle: "Exchange1",wageTitle:"wageTitle2"}
{id: 4, deductionTypeId: 1, deductionTypeTitle:"TypeTitle2",deductionExchangeTypeId: 4,deductionExchangeTypeTitle: "Exchange2",wageTitle:"wageTitle3"}
{id: 5, deductionTypeId: 1, deductionTypeTitle:"TypeTitle2",deductionExchangeTypeId: 5, deductionExchangeTypeTitle: "Exchange3",wageTitle:"wageTitle4"}
{id: 9, deductionTypeId: 6,deductionTypeTitle:"TypeTitle1",deductionExchangeTypeId: 3 ,deductionExchangeTypeTitle: "Exchange1",wageTitle:"wageTitle5"}
{id: 10, deductionTypeId: 6,deductionTypeTitle:"TypeTitle1",deductionExchangeTypeId: 3,deductionExchangeTypeTitle: "Exchange1",wageTitle:"wageTitle6"}
{id: 11, deductionTypeId: 6,deductionTypeTitle:"TypeTitle1",deductionExchangeTypeId: 3,deductionExchangeTypeTitle: "Exchange1",wageTitle:"wageTitle7"}
{id: 12, deductionTypeId: 6,deductionTypeTitle:"TypeTitle1",deductionExchangeTypeId: 3,deductionExchangeTypeTitle: "Exchange1",wageTitle:"wageTitle8"}]
And I want to grouping it in react js like this
-TypeTitle1
-Exchange1
.wageTitle1
.wageTitle2
.wageTitle6
.wageTitle7
.wageTitle8
-TypeTitle2
-Exchange2
.wageTitle3
-Exchange3
.wageTitle4
You could use Lodash to transform your data using groupBy, mapValues, and flatMap.
import _ from 'lodash';
const data = [
{
id: 6,
deductionTypeId: 6,
deductionTypeTitle: 'TypeTitle1',
deductionExchangeTypeId: 3,
deductionExchangeTypeTitle: 'Exchange1',
wageTitle: 'wageTitle1',
},
{
id: 8,
deductionTypeId: 6,
deductionTypeTitle: 'TypeTitle1',
deductionExchangeTypeId: 3,
deductionExchangeTypeTitle: 'Exchange1',
wageTitle: 'wageTitle2',
},
{
id: 4,
deductionTypeId: 1,
deductionTypeTitle: 'TypeTitle2',
deductionExchangeTypeId: 4,
deductionExchangeTypeTitle: 'Exchange2',
wageTitle: 'wageTitle3',
},
{
id: 5,
deductionTypeId: 1,
deductionTypeTitle: 'TypeTitle2',
deductionExchangeTypeId: 5,
deductionExchangeTypeTitle: 'Exchange3',
wageTitle: 'wageTitle4',
},
{
id: 9,
deductionTypeId: 6,
deductionTypeTitle: 'TypeTitle1',
deductionExchangeTypeId: 3,
deductionExchangeTypeTitle: 'Exchange1',
wageTitle: 'wageTitle5',
},
{
id: 10,
deductionTypeId: 6,
deductionTypeTitle: 'TypeTitle1',
deductionExchangeTypeId: 3,
deductionExchangeTypeTitle: 'Exchange1',
wageTitle: 'wageTitle6',
},
{
id: 11,
deductionTypeId: 6,
deductionTypeTitle: 'TypeTitle1',
deductionExchangeTypeId: 3,
deductionExchangeTypeTitle: 'Exchange1',
wageTitle: 'wageTitle7',
},
{
id: 12,
deductionTypeId: 6,
deductionTypeTitle: 'TypeTitle1',
deductionExchangeTypeId: 3,
deductionExchangeTypeTitle: 'Exchange1',
wageTitle: 'wageTitle8',
},
];
const result = _(data)
.groupBy('deductionTypeTitle')
.mapValues((items) =>
_(items)
.groupBy('deductionExchangeTypeTitle')
.mapValues((items) =>
_(items)
.flatMap((item) => item.wageTitle)
.value(),
)
.value(),
)
.value();
// result:
// {
// TypeTitle1: {
// Exchange1: ['wageTitle1', 'wageTitle2', 'wageTitle5', 'wageTitle6', 'wageTitle7', 'wageTitle8'],
// },
// TypeTitle2: { Exchange2: ['wageTitle3'], Exchange3: ['wageTitle4'] },
// }
``
This may be one possible solution to achieve the desired objective.
Code Snippet
If the UI is not needed, simply use the method: groupAndSort to obtain the desired array which will be sorted in the desired order.
const Thingy = ({data, ...props}) => {
const groupAndSort = arr => (
[...arr.map(x => ({...x}))]
.map(x => ({...x, l1: "", l2: "", l3: ""}))
.sort((a, b) => (
a.deductionTypeTitle === b.deductionTypeTitle
? a.deductionExchangeTypeTitle === b.deductionExchangeTypeTitle
? a.wageTitle === b.wageTitle
? 1
: a.wageTitle > b.wageTitle
? 1
: -1
: a.deductionExchangeTypeTitle > b.deductionExchangeTypeTitle
? 1
: -1
: a.deductionTypeTitle > b.deductionTypeTitle
? 1
: -1
))
.map(
(x, i, a) => {
if (i === 0) {
return ({
...x,
l1: x.deductionTypeTitle,
l2: x.deductionExchangeTypeTitle,
l3: x.wageTitle
})
} else {
const t = {...x};
if (x.deductionTypeTitle !== a[i-1].deductionTypeTitle) {
t.l1 = x.deductionTypeTitle
};
if (x.deductionExchangeTypeTitle !== a[i-1].deductionExchangeTypeTitle) {
t.l2 = x.deductionExchangeTypeTitle
};
if (x.wageTitle !== a[i-1].wageTitle) {
t.l3 = x.wageTitle
};
return t;
}
}
)
);
return(
<div>
<h4>Desired Display</h4>
{
groupAndSort(data)
.map(
({l1, l2, l3}) => (
<div>
<div>{l1}</div>
<div> {l2}</div>
<div> {l3}</div>
</div>
)
)
}
<br/><br/>
<h4>Sorted-Grouped Data-Array</h4>
{
JSON.stringify(groupAndSort(data))
}
</div>
);
};
const rawData = [{
id: 6,
deductionTypeId: 6,
deductionTypeTitle: "TypeTitle1",
deductionExchangeTypeId: 3,
deductionExchangeTypeTitle: "Exchange1",
wageTitle: "wageTitle1"
}, {
id: 8,
deductionTypeId: 6,
deductionTypeTitle: "TypeTitle1",
deductionExchangeTypeId: 3,
deductionExchangeTypeTitle: "Exchange1",
wageTitle: "wageTitle2"
}, {
id: 4,
deductionTypeId: 1,
deductionTypeTitle: "TypeTitle2",
deductionExchangeTypeId: 4,
deductionExchangeTypeTitle: "Exchange2",
wageTitle: "wageTitle3"
}, {
id: 5,
deductionTypeId: 1,
deductionTypeTitle: "TypeTitle2",
deductionExchangeTypeId: 5,
deductionExchangeTypeTitle: "Exchange3",
wageTitle: "wageTitle4"
}, {
id: 9,
deductionTypeId: 6,
deductionTypeTitle: "TypeTitle1",
deductionExchangeTypeId: 3,
deductionExchangeTypeTitle: "Exchange1",
wageTitle: "wageTitle5"
}, {
id: 10,
deductionTypeId: 6,
deductionTypeTitle: "TypeTitle1",
deductionExchangeTypeId: 3,
deductionExchangeTypeTitle: "Exchange1",
wageTitle: "wageTitle6"
}, {
id: 11,
deductionTypeId: 6,
deductionTypeTitle: "TypeTitle1",
deductionExchangeTypeId: 3,
deductionExchangeTypeTitle: "Exchange1",
wageTitle: "wageTitle7"
}, {
id: 12,
deductionTypeId: 6,
deductionTypeTitle: "TypeTitle1",
deductionExchangeTypeId: 3,
deductionExchangeTypeTitle: "Exchange1",
wageTitle: "wageTitle8"
}];
ReactDOM.render(
<div>
<h3>DEMO - Sort And Group Data</h3>
<Thingy data={rawData} />
</div>,
document.getElementById("rd")
);
<div id="rd"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
Explanation
Method: groupAndSort
First, deep-clone the array (so the original remains as-is)
This is done using [...arr.map(x => ({...x})] --> multiple ... spread operators
Now, add 3 props l1, l2, l3 to each array element
Use .sort checking to see if each of the levels match (ie, Type, Exchange, Wage Titles)
The nested ternary operators ?: may be replaced by if ... else if ... construct (if preferred)
Finally, .map one last time to populate the new props added (ie, l1, l2, l3)
The implicit return within the method groupAndSort returns the resulting array
JSX:
First, use .map to iterate the result
Render l1, l2, l3 in individual lines
Next, for reference use JSON.stringify to render the actual array returned from the method groupAndSort
Related
This question builds on many similar ones like Construct hierarchy tree from flat list with parent field?
However the twist is that there is no parent id.
e.g.
[
{id: 1, depth: 1, ...},
{id: 2, depth: 2, ...},
{id: 3, depth: 3, ...},
{id: 4, depth: 2, ...},
{id: 5, depth: 1, ...},
{id: 6, depth: 2, ...},
{id: 7, depth: 2, ...},
{id: 8, depth: 1, ...},
{id: 9, depth: 2, ...},
{id: 10, depth: 3, ...},
{id: 11, depth: 3, ...},
]
What is a performant way to construct the following tree?
Note that the children always come after the parent i.e. one can see the tree from the depth value. For example, id 2 is a child of id 1 since its depth is 2 and id 1 has a depth of 1. id 3 is a child of id 2 since id 3 has a depth of 3. id 4 is a child of id 1 not id 3 because id 4 has a depth of 2 (a step up) from id 3's depth of 3
\\tree digram
1
2
3
4
5
6
7
8
9
10
11
Should have values like
[
{id:1, depth:1, children: [
{id: 2, depth: 2, children: [...]},
...
]},
{id:5, depth:1, children: [...]},
{id:6, depth:1, children: [...]},
]
You can use an array for this that has an index for each depth. At every moment, it will represent a path from the (virtual) root to the current node. When dealing with a node, its parent will sit at index depth-1, where it can be inserted in that parent's children property, and the node itself will be placed at index depth:
function createForest(flatdata) {
const path = [{ children: [] }];
for (const obj of flatdata) {
path[obj.depth - 1].children.push(path[obj.depth] = { ...obj, children: [] });
}
return path[0].children;
}
// demo
const flatdata = [{id: 1, depth: 1},{id: 2, depth: 2},{id: 3, depth: 3},{id: 4, depth: 2},{id: 5, depth: 1},{id: 6, depth: 2},{id: 7, depth: 2},{id: 8, depth: 1},{id: 9, depth: 2},{id: 10, depth: 3},{id: 11, depth: 3}];
const roots = createForest(flatdata);
console.log(roots);
Irregular depths
If the depth values do not correspond to the actual depth of the nodes, but leave gaps, then use a "dictionary" (a plain object) to record the mapping of the depth property values with which real depth they correspond with:
function createForest(flatdata) {
const path = [{ children: [] }];
const depthMap = { 0: 0 };
for (const obj of flatdata) {
path[(depthMap[obj.depth] ??= path.length) - 1].children.push(
path[depthMap[obj.depth]] = { ...obj, children: []}
);
}
return path[0].children;
}
// demo
const flatdata = [{id: 1, depth: 10},{id: 2, depth: 20},{id: 3, depth: 30},{id: 4, depth: 20},{id: 5, depth: 10},{id: 6, depth: 20},{id: 7, depth: 20},{id: 8, depth: 10},{id: 9, depth: 20},{id: 10, depth: 30},{id: 11, depth: 30}];
const roots = createForest(flatdata);
console.log(roots);
If however, the only irregularity is that the depth does not always start at 1, but sometimes at 2, it will be more efficient to prefix the input data with a dummy depth-one node, use the first function, and then remove the dummy "root" (with depth 1) from the result.
Go through the array and add each item to the tree as well as to a trail of breadcrumbs. Each next item either goes as a child to the last one or you backtrack through the breadcrumb trail to the correct depth where it needs to be inserted:
const peek = arr =>
arr[arr.length-1];
function toTree(arr) {
const tree = [];
const trail = [];
for (const item of arr) {
while ((peek(trail)?.depth ?? 0) >= item.depth) {
trail.pop();
}
const current = peek(trail)?.children ?? tree;
const treeNode = {...item, children: []};
current.push(treeNode);
trail.push(treeNode);
}
return tree;
}
const array = [
{id: 1, depth: 1, },
{id: 2, depth: 2, },
{id: 3, depth: 3, },
{id: 4, depth: 2, },
{id: 5, depth: 1, },
{id: 6, depth: 2, },
{id: 7, depth: 2, },
{id: 8, depth: 1, },
{id: 9, depth: 2, },
{id: 10, depth: 3 },
{id: 11, depth: 3 },
]
console.log(toTree(array));
This solution clones each item, in order to add the .children property. If no cloning is necessary, item can be directly mutated.
You could take an array of the last inserted objects.
const
data = [{ id: 1, depth: 1 }, { id: 2, depth: 2 }, { id: 3, depth: 3 }, { id: 4, depth: 2 }, { id: 5, depth: 1 }, { id: 6, depth: 2 }, { id: 7, depth: 2 }, { id: 8, depth: 1 }, { id: 9, depth: 2 }, { id: 10, depth: 3 }, { id: 11, depth: 3 }],
result = data.reduce((r, { depth, ...o }) => {
r[depth - 1].push({ ...o, children: r[depth] = [] });
return r;
}, [[]])[0];
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
My starting data set is an array of objects containing metrics, each containing an ID. I need to convert this data set into an array of aggregates, by ID. For example:
const startingArray = [
{ id: 1, metricA: 5, metricB: 8, metricC: 1 }
{ id: 2, metricA: 4, metricB: 0, metricC: 7 }
{ id: 1, metricA: 9, metricB: 8, metricC: 2 }
{ id: 3, metricA: 1, metricB: 8, metricC: 2 }
{ id: 3, metricA: 6, metricB: 6, metricC: 1 }
{ id: 2, metricA: 3, metricB: 1, metricC: 9 }
{ id: 1, metricA: 3, metricB: 9, metricC: 8 }
]
const aggregates = {};
startingArray.forEach((item) => {
if (!aggregates[item.id]) {
aggregates[item.id] = {
id: item.id,
metricA: item.metricA,
metricB: item.metricB,
metricC: item.metricC
}
} else {
aggregates[item.id].metricA += item.metricA,
aggregates[item.id].metricB += item.metricB,
aggregates[item.id].metricC += item.metricC
}
});
// convert to flat array using lodash toArray() method
const endingArray = toArray(aggregates);
// results:
// [
// { id: 1, metricA: 17, metricB: 25, metricC: 11 }
// { id: 2, metricA: 5, metricB: 1, metricC: 16 }
// { id: 3, metricA: 5, metricB: 8, metricC: 3 }
// ]
The arrays can be massive, what is the most efficient way of processing this data set?
You could destructure id from the object and collect the rest for getting all entries and create a new object and sum all rest properties.
const
data = [{ id: 1, metricA: 5, metricB: 8, metricC: 1 }, { id: 2, metricA: 4, metricB: 0, metricC: 7 }, { id: 1, metricA: 9, metricB: 8, metricC: 2 }, { id: 3, metricA: 1, metricB: 8, metricC: 2 }, { id: 3, metricA: 6, metricB: 6, metricC: 1 }, { id: 2, metricA: 3, metricB: 1, metricC: 9 }, { id: 1, metricA: 3, metricB: 9, metricC: 8 }],
result = Object.values(data.reduce((r, { id, ...o }) => {
Object.entries(o).forEach(([k, v]) => {
r[id] ??= { id };
r[id][k] = (r[id][k] || 0) + v;
});
return r;
}, {}));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
The data structure that I am trying to achieve would look as so :
I would like the list_id to become a key in a object, and hold all the id's of the items that have the matching list id.
var lists = { (list_id)1 : [1, 2, 3]
(list_id)2 : [4, 5, 6]
(list_id)3 : [7, 8, 9]
(list_id)4 : [10, 11, 12] };
this object is created from a json data structure that looks like this:
let json = [{ id: 1, list_id: 1 }, { id: 2, list_id: 1 },
{id: 3, list_id: 1 }, {id: 4, list_id: 2 },
{id: 5, list_id: 2 }, {id: 6, list_id: 2 },
{id: 7, list_id: 3 }, {id: 8, list_id: 3 },
{id: 9, list_id: 3 }, {id: 10, list_id: 4 },
{id: 11, list_id: 4 }, {id: 12, list_id: 4 }]
I can make an object that holds all the list_id's as keys but am getting stumped on pushing the actions_id into the value pair array with the matching list id.
let listAll = {};
json.forEach(function(lista, index, listb) {
listAll[lista.list_id] = [];
if ( listAll[lista.list_id] === lista.list_id){
listAll[lista.list_id].push(lista.id)
} else {
listAll[lista.list_id] = [lista.id];
}
});
My goal is to have and object that contains a key for every list_id currently avaliable from the actions.
Then add every action that contains the matching list_id into a value pair array.
the current output of this code is
{ '1': [ 3 ], '2': [ 6 ], '3': [ 9 ], '4': [ 12 ] }
which does not contain all numbers, each array should contain 3 numbers.
An alternative is using the function reduce to group the objects by a specific key = ['list_id', list_id].join('').
let json = [{ id: 1, list_id: 1 }, { id: 2, list_id: 1 }, {id: 3, list_id: 1 }, {id: 4, list_id: 2 }, {id: 5, list_id: 2 }, {id: 6, list_id: 2 }, {id: 7, list_id: 3 }, {id: 8, list_id: 3 }, {id: 9, list_id: 3 }, {id: 10, list_id: 4 }, {id: 11, list_id: 4 }, {id: 12, list_id: 4 }],
result = json.reduce((a, {id, list_id}) => {
let key = ['list_id', list_id].join(''); // For example: this is creating ['list_id', 1] to list_id1
(a[key] || (a[key] = [])).push(id);
return a;
}, Object.create(null)/*This is only to create an object without prototype -> {}*/);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Why don't you try hasOwnProperty instead?
var listAll = {};
json.forEach(function(list, index) {
if (listAll.hasOwnProperty(list.list_id)) {
listAll[list.list_id].push(list.id);
}else {
listAll[list.list_id] = [list.id];
}
});
console.log(listAll);
Stocks: [{
PRN: 1,
PID: 1,
Qty: 3,
SlNos: [1, 2, 3]
}, {
PRN: 1,
PID: 2,
Qty: 4,
SlNos: [10, 11, 12, 13]
}, {
PRN: 2,
PID: 1,
Qty: 3,
SlNos: [4, 5, 6]
}, {
PRN: 2,
PID: 2,
Qty: 4,
SlNos: [14, 15, 16, 17]
}]
I want this array as bellow with Lodash
Stocks: [{
PID: 1,
Qty: 6,
SlNos: [1, 2, 3, 4, 5, 6]
}, {
PID: 2,
Qty: 4,
SlNos: [10, 11, 12, 13, 14, 15, 16, 17]
}]
Here is a solution with _lodash:
var stocks = [{ PRN: 1, PID: 1, Qty: 3, SlNos: [1, 2, 3] }, { PRN: 1, PID: 2, Qty: 4, SlNos: [10, 11, 12, 13] }, { PRN: 2, PID: 1, Qty: 3, SlNos: [4, 5, 6] }, { PRN: 2, PID: 2, Qty: 4, SlNos: [14, 15, 16, 17] }]
const result = _.reduce(stocks, (r, {PRN, ...c}) => {
let _c = _.find(r, {'PID': c.PID})
if(_c)
_c = _.mergeWith(_c, c, (ov, sv, k) => _.includes(['Qty','SlNos'], k) ? _.isArray(sv) ? (ov || []).concat(sv) : _.isNumber(sv) ? sv + (ov || 0) : sv : ov)
else
r.push(c)
return r
}, [])
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
We are using reduce with mergeWith (which is the main thing here really) plus a little bit of includes.
Here is a solution without lodash that will do the trick:
var stocks = [{ PRN: 1, PID: 1, Qty: 3, SlNos: [1, 2, 3] }, { PRN: 1, PID: 2, Qty: 4, SlNos: [10, 11, 12, 13] }, { PRN: 2, PID: 1, Qty: 3, SlNos: [4, 5, 6] }, { PRN: 2, PID: 2, Qty: 4, SlNos: [14, 15, 16, 17] }]
const result = stocks.reduce((r, c) => {
_c = r.find(x => x.PID === c.PID)
if (_c) {
_c.PID = c.PID
_c.Qty = _c.Qty + c.Qty
_c.SlNos = _c.SlNos ? _c.SlNos.concat(c.SlNos) : c.SlNos
} else {
r.push(!delete(c.PRN) || c)
}
return r
}, [])
console.log(result)
The idea is to use reduce and first find if we had already that object by PID if so sum the values if not insert to the final array. Since we are going through each record that logic does the trick in one loop.
I have a collection of data like this :
var data = [
{"p301a":"10","p301b":"7","p301c":"7","p301d":"3","p301e":"8","p301f":"8","p301g":"8","p301h":"8","p301i":"8","p301j":"8","p301k":"8","p301l":"8","p301m":"8","p301n":"8","p301o":"8","age":"31-40 years","profesion":"2","position":"2"},
{"p301a":"5","p301b":"4","p301c":"4","p301d":"4","p301e":"4","p301f":"4","p301g":"4","p301h":"4","p301i":"4","p301j":"4","p301k":"4","p301l":"4","p301m":"4","p301n":"4","p301o":"4","age":"24-30 years","profesion":"2","position":"2"},
{"p301a":"8","p301b":"8","p301c":"3","p301d":"9","p301e":"9","p301f":"4","p301g":"9","p301h":"4","p301i":"2","p301j":"9","p301k":"4","p301l":"9","p301m":"4","p301n":"9","p301o":"9","age":"31-40 years","profesion":"1","position":"3"},
{"p301a":"3","p301b":"3","p301c":"3","p301d":"8","p301e":"9","p301f":"9","p301g":"8","p301h":"9","p301i":"9","p301j":"9","p301k":"8","p301l":"8","p301m":"3","p301n":"3","p301o":"3","age":"31-40 years","profesion":"1","position":"3"},
{"p301a":"6","p301b":"5","p301c":"5","p301d":"8","p301e":"7","p301f":"5","p301g":"6","p301h":"2","p301i":"6","p301j":"5","p301k":"7","p301l":"7","p301m":"4","p301n":"8","p301o":"3","age":"24-30 years","profesion":"1","position":"2"},
{"p301a":"8","p301b":"8","p301c":"4","p301d":"4","p301e":"4","p301f":"5","p301g":"4","p301h":"4","p301i":"4","p301j":"4","p301k":"4","p301l":"9","p301m":"9","p301n":"9","p301o":"4","age":"31-40 years","profesion":"2","position":"3"}
];
From the data I want to create a Stacked percentage column from highchartjs,
With the stipulation of each bar having the number of p301a = 1, p301a = 2 and so on up to 10.
I think it can be done using underscore.js, but I do not know how.
i want to create somthing like this
example
or i want to get data like this :
var xAxis: {
categories: ['a', 'b', 'c' ... 'o' ]
},
var series: [{
name: '1',
data: [5, 3, 4, 7, 2, 5, 9, 5, 8, 4, 5, 7, 8, 3, 4]
}, {
name: '2',
data: [2, 2, 3, 2, 1, 5, 9, 5, 8, 4, 5, 7, 8, 3, 4]
}, {
name: '3',
data: [3, 4, 4, 2, 5, 5, 9, 5, 8, 4, 5, 7, 8, 3, 4]
}, {
name: '4',
data: [3, 4, 4, 2, 5, 5, 9, 5, 8, 4, 5, 7, 8, 3, 4]
}, ... (until 10)]
Sorry for the english
Please help