sorting array object based on other array - javascript

i am creating a table based on the list tablelist given,where i am creating my table header from tablefield,but i want my header to be ordered according to tableordering property
var tablelist = {
"member": {
"name": "Richie",
"id": 5
},
"submission_time": "10/03/2018 00:00:00",
"tablefield": [
{
"field_name": "top1",
"value": 1,
},
{
"field_name": "top5",
"value": 5,
},
{
"field_name": "top3",
"value": 3,
},
{
"field_name": "top2",
"value": 2,
},
{
"field_name": "top4",
"value": 4,
},
],
"tableordering": [
"member",
"top1",
"top2",
"top3",
"top4",
"top5",
"submission_time",
]
}
i want my list result to be like
var result = [{member:"Richie",top1:"1",top2:"1",top3:"1",top4:"1",top5:"1",submission-time:"1"}]
below is the code
var lists = tablelist.reduce((acc, cur) => {
acc[cur.field_name] = cur.value;
return acc;
}, {});
var listres = Object.assign({}, lists, {
member: i.member.name,
submission_time: i.submission_time
});
but then sorting with tableordering, i do not know,could someone help

🏴󠁡󠁦󠁷󠁡󠁲󠁿 Divide and rule or reduce and map:
const tablelist = {
member: {name: `Richie`, id: 5},
submission_time: `10/03/2018 00:00:00`,
tablefield: [
{field_name: `top1`, value: 1},
{field_name: `top5`, value: 5},
{field_name: `top3`, value: 3},
{field_name: `top2`, value: 2},
{field_name: `top4`, value: 4}
],
tableordering: [
`member`,
`top1`,
`top2`,
`top3`,
`top4`,
`top5`,
`submission_time`
]
}
const {member: {name: member}, submission_time} = tablelist
const fields = tablelist.tablefield.reduce((list, {field_name, value}) => {
list[field_name] = value
return list
}, {})
const data = {member, submission_time, ...fields}
const result = [tablelist.tableordering.reduce((list, key) => {
list[key]= data[key]
return list
}, {})]
console.log(result)

Related

flatten array and put child array into an array of object

I struggled with a problem for more than an hour, how can I turn this nested array
[
[
{
"name": "1",
}
],
[
{
"name": "a",
},
{
"name": "b",
}
]
]
into this:
[
{
name: '1',
},
{
id: 'a-b',
grouped: [
{
name: 'a',
},
{
name: 'b',
},
],
},
]
I don't mind using lodash. Not sure should I flatten it before anything else would make things easier.
You could use map() to form the id and grab the parts needed to reconstruct the new array.
const data = [
[{
"name": "1",
}],
[{
"name": "a",
},
{
"name": "b",
}
]
];
const result = [
...data[0],
{
id: data[1].map(r => r.name).join("-"),
grouped: data[1]
}
];
console.log(result);
to flatten the array is a good start. That will remove the superfluous dimension from the rawArray:
const newArray = array.flat()
Now you have an array with three simple objects. The first will remain unchanged. The second element of your finalArray needs to be an object, so let's create it:
const obj = {}
the obj has two keys: id and grouped. The property of id is a string that we can create like this:
obj.id = newArray[1].name + "-" + newArray[2].name
the property of grouped remains the same:
obj.grouped = array[1]
so the finalArray is now straight forward:
const finalArray = [ newArray[0], obj ]
Put it all together in a function:
const rawArray1 = [
[
{
"name": "1a",
}
],
[
{
"name": "a",
},
{
"name": "b",
}
]
]
const rawArray2 = [
[
{
"name": "1b",
}
],
[
{
"name": "aa",
},
{
"name": "bb",
}
]
]
transformArray( rawArray1 )
transformArray( rawArray2 )
function transformArray( array ){
const newArray = array.flat()
const obj = {}
obj.id = newArray[1].name + "-" + newArray[2].name
obj.grouped = array[1]
const finalArray = [ newArray[0], obj ]
console.log(finalArray)
return finalArray
}
I managed to solve it using simple forEach, push, and flat. It's more simple than I thought, I was confused and stuck with map and reduce.
let result = [];
[
[{
"name": "1",
}],
[{
"name": "a",
},
{
"name": "b",
}
]
].forEach((val) => {
const [{
name
}] = val
if (val.length === 1) {
result.push({
name,
})
} else if (val.length > 1) {
result.push({
id: val.map(val2 => val2.name).join('-'),
grouped: val
})
}
})
console.log(result.flat())
const array1 = [
[{ name: "1" }],
[
{ name: "a" },
{ name: "b" }
]
]
const array2 = [
[{ name: "2" }],
[
{ name: "aa" },
{ name: "bb" },
{ name: "cc" }
]
]
transformArray( array1 )
transformArray( array2 )
function transformArray( array ){
const result = []
// destructure first array element for the first object:
const [ nameObj ] = array[0]
result.push( nameObj )
// map each object of the second array element into an
// an array of names, and then join the names together:
const dataObj = {}
dataObj.id = array[1].map(obj => obj.name).join('-')
dataObj.grouped = array[1]
result.push( dataObj )
console.log( result )
return result
}

Sort an array by a list of it's fields

Let's say I have an array of objects:
Objects = [
{ "id": 1, "name": Joseph, function: "preacher"},
{ "id": 2, "name": Ann, function: "singer"},
{ "id": 3, "name": Miles, function: "preacher"},
{ "id": 4, "name": Jack, function: "singer"},
{ "id": 5, "name": Igor, function: "secretary"}
];
And also an array of properties:
sort = ['function', 'name'];
I have to sort the Objects array, using a combination of properties(sort array).
So I did it like this:
const intlCollator = new Intl.Collator('pt-BR', { usage: 'sort' });
Objects.sort(
(x, y) =>
(intlCollator.compare(x[sort[0]], y[sort[0]])) ||
(intlCollator.compare(x[sort[1]], y[sort[1]])) ||
(intlCollator.compare(x[sort[2]], y[sort[2]]))
);
How would I make the sorting dynamic?
I mean, iterate using variable sort combinations.
For example:
sort = ['function', 'name'];
Or:
sort = ['name'];
You could iterate the keys until a comparing returns a not falsy value.
const
objects = [{ id: 1, name: "Joseph", function: "preacher" }, { id: 2, name: "Ann", function: "singer" }, { id: 3, name: "Miles", function: "preacher" }, { id: 4, name: "Jack", function: "singer" }, { id: 5, name: "Igor", function: "secretary" }],
intlCollator = new Intl.Collator('pt-BR', { usage: 'sort' }),
sort = ['function', 'name'];
objects.sort((a, b) => {
let r;
sort.some(k => r = intlCollator.compare(a[k], b[k]));
return r;
});
console.log(objects);
Since ES10 sort is stable. That means you can first sort using the first key, then sort the second and so on.
const Objects = [
{ "id": 1, "name": "Joseph", function: "preacher"},
{ "id": 2, "name": "Ann", function: "singer"},
{ "id": 3, "name": "Miles", function: "preacher"},
{ "id": 4, "name": "Jack", function: "singer"},
{ "id": 5, "name": "Igor", function: "secretary"}
];
const sort = ['name', 'function'];
const intlCollator = new Intl.Collator('pt-BR', { usage: 'sort' });
sort.forEach(s => {
Objects.sort((l, r) => intlCollator.compare(l[s], r[s]));
});
console.log(Objects);

how to combine array of object fast or in optimized way

I have two Array of objects [{id:'KS001', name: 'albedo'}] this is the first array which consist of 900+ objects.
{
"changePoints": [
{
"Point": {
"name": "001",
"id": "KS001",
"siteID": "258628",
"connectorGroups": [
{
"connectorGroupID": 1,
"connectors": [
{
"connectorID": "1",
"connectorStatus": "AVAILABLE"
}
]
},
{
"connectorGroupID": 2,
"connectors": [
{
"connectorID": "2",
"connectorStatus": "AVAILABLE"
}
]
}
]
}
},
],
}
this is the second array that contains objects which have a point and id this id map with the first array as an identifier I need to check each connectorStatus in the second array with the corresponding id and add a new key to the first array status set "AVAILABLE" else not "NOT AVAILABLE"
I need to find the fastest way to do this
const object1 = {
name: 'Flavio'
}
const object2 = {
age: 35
}
const object3 = {...object1, ...object2 } //{name: "Flavio", age: 35}
const a = { b: 1, c: 2 };
const d = { e: 1, f: 2 };
const ad = { ...a, ...d }; // { b: 1, c: 2, e: 1, f: 2 }

How do I "flatten" an object into an array of arrays

I have this object:
{
"value": "face",
"next": [
{
"value": "tace",
"next": [
{
"value": "tale",
"next": [
{
"value": "talk",
"next": []
}
]
},
{
"value": "tack",
"next": [
{
"value": "talk",
"next": []
}
]
}
]
},
{
"value": "fack",
"next": [
{
"value": "tack",
"next": [
{
"value": "talk",
"next": []
}
]
},
{
"value": "falk",
"next": [
{
"value": "talk",
"next": []
}
]
}
]
}
]
}
What is the best way to iterate over it and create this array of arrays:
[
["face", "tace", "tale", "talk"],
["face", "tace", "tack", "talk"],
["face", "fack", "tack", "talk"],
["face" ,"fack", "falk", "talk"]
]
I basically want to "flatten" the object into the array format by traversing down each branch of the object and producing an array of strings for each branch.
You can do this by creating recursive function using reduce method, that will store previous values and when there is no elements in next property it will current copy push to result array.
const data = {"value":"face","next":[{"value":"tace","next":[{"value":"tale","next":[{"value":"talk","next":[]}]},{"value":"tack","next":[{"value":"talk","next":[]}]}]},{"value":"fack","next":[{"value":"tack","next":[{"value":"talk","next":[]}]},{"value":"falk","next":[{"value":"talk","next":[]}]}]}]}
const flatten = (obj, prev = []) => {
const next = prev.concat(obj.value)
return obj.next.reduce((r, e) => {
if(e.next.length) r.push(...flatten(e, next))
else r.push(next.slice().concat(e.value));
return r;
}, [])
}
const result = flatten(data);
console.log(result);
You can use recursion with Array.forEach() to iterate the next property, and add the previous items. When next is empty, take everything, flatten, and push to the result:
const flatAll = (data) => {
const result = [];
const fn = ({ value, next }, prev = []) => {
if(next.length) next.forEach(o => fn(o, [prev, value]));
else result.push([prev, value].flat(Infinity));
};
fn(data);
return result;
}
const data = {"value":"face","next":[{"value":"tace","next":[{"value":"tale","next":[{"value":"talk","next":[]}]},{"value":"tack","next":[{"value":"talk","next":[]}]}]},{"value":"fack","next":[{"value":"tack","next":[{"value":"talk","next":[]}]},{"value":"falk","next":[{"value":"talk","next":[]}]}]}]};
const result = flatAll(data);
console.log(result);
You could use an independent recursive function and collect the last item and build an arrayof the given values for every level.
const
flat = (value, next) => next
.reduce((r, { value, next }) => {
if (next.length) r.push(...flat(value, next));
else r.push([value]);
return r;
}, [])
.map(q => [value, ...q]);
var data = { value: "face", next: [{ value: "tace", next: [{ value: "tale", next: [{ value: "talk", next: [] }] }, { value: "tack", next: [{ value: "talk", next: [] }] }] }, { value: "fack", next: [{ value: "tack", next: [{ value: "talk", next: [] }] }, { value: "falk", next: [{ value: "talk", next: [] }] }] }] },
result = flat(data.value, data.next);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Pulling single property from json when array of values are given

How can we retrieve name from the json, when array of ids are provided.
[
{
"id": 0,
"name": "salesTransNo"
},
{
"id": 1,
"name": "terminalNo"
},
{
"id": 2,
"name": "salesTransDate"
},
{
"id": 3,
"name": "salesTransTime"
},
{
"id": 4,
"name": "exceptionAmount"
},
{
"id": 5,
"name": "laneNumber"
}
]
I want to retrieve only names into an array from the JSON, when array of id values are given
eg: array of id's : [2,4,5]
Output should be:
["salesTransDate","exceptionAmount","LaneNumber"]
How can we achieve this with Lodash or with JavaScript ?
I used _.find and used _.map to pull only name from the result, but it's only working for single value, if I were to pass an array like [2,4,5] it's not working.
You could filter the objects and then map the wanted property.
var data = [{ id: 0, name: "salesTransNo" }, { id: 1, name: "terminalNo" }, { id: 2, name: "salesTransDate" }, { id: 3, name: "salesTransTime" }, { id: 4, name: "exceptionAmount" }, { id: 5, name: "laneNumber" }],
ids = [2, 4, 5],
result = data
.filter(({ id }) => ids.includes(id))
.map(({ name }) => name);
console.log(result);
Vanilla JS:
var arr = [
{ "id": 0, "name": "salesTransNo" },
{ "id": 1, "name": "terminalNo" },
{ "id": 2, "name": "salesTransDate" },
{ "id": 3, "name": "salesTransTime" },
{ "id": 4, "name": "exceptionAmount" },
{ "id": 5, "name": "laneNumber" }
];
var indexes = arr.map ( function ( d ) { return d.id; });
var id = 4; // Requested arr.id item
var select_name = arr[indexes.indexOf(id)].name;
If you wish to return multiple results, you can build a function like so:
function getNamesFromArr ( list_of_ids ) {
var result = [];
for ( var i = 0; i < list_of_ids.length; i++ ) {
var indexes = arr.map ( function ( d ) { return d.id; });
var select_name = arr[indexes.indexOf(list_of_ids[i])].name;
result.push ( select_name );
}
return result;
}
getNamesFromArr ([ 2, 4, 5 ]); // Returns ["salesTransDate", "exceptionAmount", "laneNumber"]
Note: I had left out error handling for simplicity. Consider catching indexOf() values of -1.
var items = [{
"id": 0,
"name": "salesTransNo"
},
{
"id": 1,
"name": "terminalNo"
},
{
"id": 2,
"name": "salesTransDate"
},
{
"id": 3,
"name": "salesTransTime"
},
{
"id": 4,
"name": "exceptionAmount"
},
{
"id": 5,
"name": "laneNumber"
}
]
var iname = items.filter(items => [2, 4, 5].includes(items.id));
for (var names of iname)
{console.log(names.name);}
You can do that with a lodash's chain using _.keyBy(), _.at(), and _.map():
var data = [{ id: 0, name: "salesTransNo" }, { id: 1, name: "terminalNo" }, { id: 2, name: "salesTransDate" }, { id: 3, name: "salesTransTime" }, { id: 4, name: "exceptionAmount" }, { id: 5, name: "laneNumber" }];
var ids = [2, 4, 5];
var result = _(data)
.keyBy('id') // convert to a dictionary by id
.at(ids) // get the items which id match the id array
.map('name') // pluck the name
.value();
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
You can use lodash#intersectionWith, wherein the arguments order must be the collection first, the ids second and the comparator at the end.
var result = _.intersectionWith(data, ids, (a, b) => a.id == b);
var data = [{
id: 0,
name: "salesTransNo"
}, {
id: 1,
name: "terminalNo"
}, {
id: 2,
name: "salesTransDate"
}, {
id: 3,
name: "salesTransTime"
}, {
id: 4,
name: "exceptionAmount"
}, {
id: 5,
name: "laneNumber"
}],
ids = [2, 4, 5];
var result = _.intersectionWith(data, ids, (a, b) => a.id == b);
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

Categories