Extract the first element from nested array into new array Angular - arrays

Here is my multi-dimensional array:
newItem = [['ID', ['item 1A','item 1B','item 1C']], ['Address',['item 2A','item 2B','item 2C']], ['Req',['item 3A', 'item 3B', 'item 3C']]]
I'm trying to extract it into a new array in the below format:
newArr = [['item 1A', 'item 2A', 'item 3A'], ['item 1B', 'item 2B', 'item 3B'], ['item 1C', 'item 2C', 'item 3C']]
Tried several ways with map, flat, etc but was unable to achieve the desired result.
Looking for help here.

What you want is transposing the matrix, and you can simply use map to achieve this:
const newItem = [
['ID', ['item 1A', 'item 1B', 'item 1C']],
['Address', ['item 2A', 'item 2B', 'item 2C']],
['Req', ['item 3A', 'item 3B', 'item 3C']]
]
const matrix = newItem.map(item => item[1]) // turn the array into matrix
const newArr = matrix[0].map((_, i) => matrix.map(item => item[i])) // transpose the matrix
console.log(newArr)

Related

react native update specific object where id = id

I have here an array of datas. And I want to update the title from the object where the key is 3.
const data = [
{
key: '1',
title: 'Title 1',
desc: 'Desc 1',
image: 'http://192.168.0.22:3000/build/photo_1621612104216_d747ced4-b313-4687-b9ac-ab5bcd78501d.jpg'
},
{
key: '2',
title: 'Title 2',
desc: 'Desc 2',
image: 'http://192.168.0.22:3000/build/photo_1621612230526_f49f2be8-6fd6-420d-b0b0-b39216418924.jpg'
},
{
key: '3',
title: 'Title 3',
desc: 'Desc 3',
image: 'http://192.168.0.22:3000/build/photo_1621612230526_f49f2be8-6fd6-420d-b0b0-b39216418924.jpg'
},
{
key: '4',
title: 'Title 4',
desc: 'Desc 4',
image: 'http://192.168.0.22:3000/build/photo_1621612104216_d747ced4-b313-4687-b9ac-ab5bcd78501d.jpg'
},
];
How I make it?
..............
.............
............
..........
...........
............
..............
The following is just one of many ways to do it:
const newData = data.map(({ key, title, ...datum }) => key === "3"
? { key, title: "newTitle", ...datum }
: {key, title, ...datum}
);
Generally you would map the previous array to the next array, checking the current key property for a match, and when found you copy also the element and update the title property, otherwise just pass through the current element.
const newData = data.map(el => el.key === '3' ? {
...el,
title: // the new title
} : el);
This is such a common pattern in React that you would extract this functionality into a function.
const updateTitleByKey = (key, title) => {
return data.map(el => el.key === key ? {
...el,
title
} : el);
};
Another example using dynamic keys:
const updatePropertyByKey = (key, name, value) => {
return data.map(el => el.key === key ? {
...el,
[name]: value
} : el);
};
const data = [
{
key: '1',
title: 'Title 1',
desc: 'Desc 1',
image: 'http://192.168.0.22:3000/build/photo_1621612104216_d747ced4-b313-4687-b9ac-ab5bcd78501d.jpg'
},
{
key: '2',
title: 'Title 2',
desc: 'Desc 2',
image: 'http://192.168.0.22:3000/build/photo_1621612230526_f49f2be8-6fd6-420d-b0b0-b39216418924.jpg'
},
{
key: '3',
title: 'Title 3',
desc: 'Desc 3',
image: 'http://192.168.0.22:3000/build/photo_1621612230526_f49f2be8-6fd6-420d-b0b0-b39216418924.jpg'
},
{
key: '4',
title: 'Title 4',
desc: 'Desc 4',
image: 'http://192.168.0.22:3000/build/photo_1621612104216_d747ced4-b313-4687-b9ac-ab5bcd78501d.jpg'
},
];
const updatePropertyByKey = (key, name, value) => {
return data.map(el => el.key === key ? {
...el,
[name]: value
} : el);
};
const newData = updatePropertyByKey('3', 'title', 'Title 3 New');
console.log(newData[2]);

Is there other solution to use `R.applySpec` without inserting the unchanged keys value?

Is there other solution to use R.applySpec without inserting the the unchanged keys value?(without needs to type id and name keys in the example, because later the keys will be change dynamically). Thank you.
Here is my input data
const data = [
[
{ id: 'data1', name: 'it is data 1', itemId: 'item1' },
{ id: 'data1', name: 'it is data 1', itemId: 'item2' }
],
[
{ id: 'data2', name: 'it is data 2', itemId: 'item1' }
],
[
{ id: 'data3', name: 'it is data 3', itemId: 'item1' },
{ id: 'data3', name: 'it is data 3', itemId: 'item2' }
]
]
And the output
[
{
id: 'data1', // this one doesn't change
name: 'it is data 1', // this one doesn't change
itemId: [ 'item1', 'item2' ]
},
{
id: 'data2', // this one doesn't change
name: 'it is data 2', // this one doesn't change
itemId: [ 'item1' ]
},
{
id: 'data3', // this one doesn't change
name: 'it is data 3', // this one doesn't change
itemId: [ 'item1', 'item2' ]
}
]
The solution to get the output using Ramda
const result = R.map(
R.applySpec({
id: R.path([0, 'id']),
name: R.path([0, 'name']), // don't need to type id or name again
itemId: R.pluck('itemId')
})
)(data)
We could certainly write something in Ramda like this:
const convert = map (lift (mergeRight) (head, pipe (pluck ('itemId'), objOf('itemId'))))
const data = [[{id: 'data1', name: 'it is data 1', itemId: 'item1'}, {id: 'data1', name: 'it is data 1', itemId: 'item2'}], [{id: 'data2', name: 'it is data 2', itemId: 'item1'}], [{id: 'data3', name: 'it is data 3', itemId: 'item1'}, {id: 'data3', name: 'it is data 3', itemId: 'item2'}]]
console .log (convert (data))
.as-console-wrapper {min-height: 100% !important; top: 0}
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.0/ramda.js"></script>
<script> const {map, lift, mergeRight, head, pipe, pluck, objOf} = R </script>
I'm not sure whether I find that more or less readable than a ES6/Ramda version, though:
const convert = map (
reduce ((a, {itemId, ...rest}) => ({...rest, itemId: [...(a .itemId || []), itemId]}), {})
)
or a plain ES6 version:
const convert = data => data .map (
ds => ds .reduce (
(a, {itemId, ...rest}) => ({...rest, itemId: [...(a .itemId || []), itemId]}),
{}
)
)
The question about applySpec is interesting. This function lets you build a new object out of the old one, but you have to entirely describe the new object. There is another function, evolve, which keeps intact all the properties of the input object, replacing only those specifically mentioned, by applying a function to their current value. But the input to the functions in evolve accepts only the current value, unlike applySpec which has access to the entire original object.
I could see some rationale for a function combining these behaviors. But I don't have a clear API in my head for how it should work. If you have some thoughts on this, and want to make a proposal, the Ramda team is always looking for suggestions.

Reordering a sequence of objects in a normalised Redux data structure

I have a normalised Redux data structure indexed by a string ID. Amongst other properties, each object in the state has a sequenceNumber which is used to display it in order in a list or grid. The items can be dragged and dropped to reorder them.
I'm struggling to find a neat, pure approach to updating the sequence numbers. What is a good way to do this in a Redux reducer?
My current state data structure is essentially:
{
'asdf': { title: 'Item 1', sequence: 0, ... },
'1234': { title: 'Item 2', sequence: 1, ... },
'zzzz': { title: 'Item 3', sequence: 2, ... }
}
My action is
{ type: REORDER_ITEMS, oldRow: 1, newRow: 0 }
Which should result in the state
{
'asdf': { title: 'Item 1', sequence: 1, ... },
'1234': { title: 'Item 2', sequence: 0, ... },
'zzzz': { title: 'Item 3', sequence: 2, ... }
}
My current reducer uses Object.keys(state).reduce() to loop through the items and modify the sequence one by one, depending on whether they are equal, greater or lesser than the desired row numbers. Is there a neater way to manage this?
You could normalize a step further : Extract the sequence in a separate state slice and store the order as an array of ids.
{
items : {
'asdf': { title: 'Item 1', ... },
'1234': { title: 'Item 2', ... },
'zzzz': { title: 'Item 3', ... }
},
sequence: ['1234', 'asdf', 'zzzz']
}
This way, you could have a separate reducer to handle actions modifying your sequence, only using array operations.

Get CheckboxGroup (or RadioGroup) values [EXTJS 3.4]

I have a checkboxgroup and a radiogroup. For both of them, I want to catch several values.
For the checkboxGroup
var DescCheck = new Ext.form.CheckboxGroup({
fieldLabel: 'Description of service : <span style="color: rgb(255, 0, 0); padding-left: 2px;">*</span>',
width : 540,
labelSeparator : '',
items: [
{boxLabel: 'Direct', name: 'Direct', inputValue: 'Direct'},
{boxLabel: 'Fixed-day', name: 'day', inputValue: 'Fixed'},
{boxLabel: 'Weekly', name: 'Weekly', inputValue: 'Weekly'}
]
});
I tried DescCheck.getValue() but it returned me
[object Object]
I tried DescCheck.getValue().inputValue and it returned me nothing.
For the radioGroup
var TypeCheck = new Ext.form.RadioGroup({
items: [
{boxLabel: 'New 1', name: '1', inputValue: '1'},
{boxLabel: 'New 2', name: '2', inputValue: '2'},
{boxLabel: 'New 3', name: '3', inputValue: '3'}
]
I tried TypeCheck.getValue().inputValue but it returned only the first selected item. How can I catch several checked boxes?
Did you tried getChecked for getting all checked boxes.
DescCheck.getChecked();
Update
You should use getValue(), It returns the array of selected values.
You can get that by looping through array like this
var selectedValue = DescCheck.getValue();
for(var i=0;i<selectedValue.length;i++){
console.log(select[i].inputValue);
}
In my project works this below...
var selectedOptions = DescCheck.getChecked(); // DescCheck.getValue();
for (var i = 0; i < selectedOptions.length; i++) {
console.log( selectedOptions[i].inputValue );
}

extjs array reader

I'm trying to create a data store with an array reader. in each of the record, there is an array of fields. However, I only need some of the fields in the record. How can I setup the array reader so that only part of the record is mapped to the data store?
For each field in the reader, just add a 'mapping' item and set it equal to the index of the item in the array it is for. eg:
var arrData = [
['Col 1', 'Col 2', 'Col 3']
['Col 1', 'Col 2', 'Col 3']
['Col 1', 'Col 2', 'Col 3']
];
var reader = new Ext.data.ArrayReader({}, [
{name: 'First Column', mapping: 0},
{name: 'Third Column', mapping: 2},
]);
This will exclude the 2nd column (zero based index)

Resources