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>
Related
I have an array of objects:
const workouts = [
{
id: 1,
name: "Bench Press",
superset_id: 1,
},
{
id: 2,
name: "Squats",
superset_id: 2,
},
{
id: 3,
name: "Shoulder Press",
superset_id: 1,
},
{
id: 4,
name: "Leg Press",
superset_id: 2,
},
...
];
What I would like to do is filter the array for objects with a matching superset_id and return a new array that looks like this:
[
[
{
id: 1,
name: "Bench Press",
superset_id: 1,
},
{
id: 3,
name: "Shoulder Press",
superset_id: 1,
},
],
[
{
id: 2,
name: "Squats",
superset_id: 2,
},
{
id: 4,
name: "Leg Press",
superset_id: 2,
},
],
...
];
How can I achieve this?
Use a combination of Math.max() and .map() to find the largest superset_id in the data, then filter the data for every superset_id. Like this:
const data = [{id:1,name:"Bench Press",superset_id:1},{id:2,name:"Squats",superset_id:2},{id:3,name:"Shoulder Press",superset_id:1},{id:4,name:"Leg Press",superset_id:2},];
const maxSuperset = Math.max(...data.map(el => el.superset_id));
const res = [];
for (let i = 1; i <= maxSuperset; i++) {
res.push(data.filter(el => el.superset_id === i));
}
console.log(res)
You can use Array#reduce with an object to store the values for each id.
const workouts=[{id:1,name:"Bench Press",superset_id:1},{id:2,name:"Squats",superset_id:2},{id:3,name:"Shoulder Press",superset_id:1},{id:4,name:"Leg Press",superset_id:2},];
let res = Object.values(
workouts.reduce((acc, curr) => {
(acc[curr.superset_id] ??= []).push(curr);
return acc;
}, {})
);
console.log(res);
As long as superset_id is incremental, this might be an idea.
const newArray = [];
array.forEach((elem) => {
if(newArray[elem.superset_id - 1] === undefined) {
newArray[elem.superset_id - 1] = [];
}
newArray[elem.superset_id - 1].push(elem);
});
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);
I am trying to sort the time. but I am unable to sort by time (hh:mm:ss) format. so i have used moments js. my array sort by time not get sorted. how sort array by using maps
I have an array of objects:
let elements =[
{
"id": 1,
"date": "02:01:02"
},
{
"id": 2,
"date": "01:01:01"
},
{
"id": 3,
"date": "03:01:01"
},
{
"id": 4,
"date": "04:01:01"
}
];
let parsedDates = new Map(
elements.map(e =>[["id", "date"],[e.id, moment(e.date, 'hh:mm:ss')]])
);
elements.sort((a, b) => parsedDates.get(a) - parsedDates.get(b));
console.log(elements.map(e => ({ id: e.id, date: e.date })));
You can lexicographical sort the time using string.localeCompare().
let times = [ { "id": 1, "date": "02:01:02" }, { "id": 2, "date": "01:01:01" }, { "id": 3, "date": "03:01:01" }, { "id": 4, "date": "04:01:01" } ];
times.sort((a,b) => a.date.localeCompare(b.date));
console.log(times);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can try this
function convertDateObj(hhmmss){
let obj = new Date();//creates a Date Object using the clients current time
let [hours,minutes,seconds] = hhmmss.split(':');
obj.setHours(+hours); // set the hours, using implicit type coercion
obj.setMinutes(minutes); //you can pass Number or String, it doesn't really matter
obj.setSeconds(seconds);
return obj;
}
let elements =[
{
"id": 1,
"date": "02:01:02"
},
{
"id": 2,
"date": "01:01:01"
},
{
"id": 3,
"date": "03:01:01"
},
{
"id": 4,
"date": "04:01:01"
}
];
elements.sort((a, b) => convertDateObj(a.date) - convertDateObj(b.date)); // Ascending order
elements.sort((a, b) => convertDateObj(b.date) - convertDateObj(a.date)); // Descending order
The parsedDates map you've created is looking like:
Map {
[ 'id', 'date' ] => [ 1, <some Date object> ],
[ 'id', 'date' ] => [ 2, <some Date object> ],
[ 'id', 'date' ] => [ 3, <some Date object> ],
[ 'id', 'date' ] => [ 4, <some Date object> ]
}
And then you try to extract from it with elements like this:
parsedDates.get({ "id": 1, "date": "02:01:02" })
This should not work, because the key in a Map is and Array instance.
Even if you were using an array as a key:
parsedDates.get([ 1, "02:01:02" ])
this still wouldn't work, as this would be a different Object reference. I mean two arrays
a = [ 1, "02:01:02" ]
b = [ 1, "02:01:02" ]
are stored in different places and are different Objects, even though their values are identical.
So, you can modify your solution a bit:
let elements =[
{
"id": 1,
"date": "02:01:02"
},
{
"id": 2,
"date": "01:01:01"
},
{
"id": 3,
"date": "03:01:01"
},
{
"id": 4,
"date": "04:01:01"
}
];
let parsedDates = new Map(
elements.map(e => [e.date, e])
);
elements = elements.map(x => x.date).sort().map(x => parsedDates.get(x))
console.log(elements)
// [
// { id: 2, date: '01:01:01' },
// { id: 1, date: '02:01:02' },
// { id: 3, date: '03:01:01' },
// { id: 4, date: '04:01:01' }
// ]
Having an array like this:
const data = [
{
"name": "Dave",
"coins": 14,
"weapons": 2,
"otherItems": 3,
"color": "red"
},
{
"name": "Vanessa",
"coins": 18,
"weapons": 1,
"otherItems": 5,
"color": "blue"
},
{
"name": "Sharon",
"coins": 9,
"weapons": 5,
"otherItems": 1,
"color": "pink"
},
{
"name": "Walter",
"coins": 9,
"weapons": 2,
"otherItems": 4,
"color": "white"
}
]
How to count sum of coins, weapons and otherItems using ES6 features? (I'm not attached to this: any simple method would be good.)
data.reduce((first, last) => first + last) generates a chain of [object Object][object Object]s...
You have to process every field separately (note that when you don't specify second parameter for reduce it will take first array object as seed and start processing from the second one):
const data = [
{
"name": "Dave",
"coins": 14,
"weapons": 2,
"otherItems": 3,
"color": "red"
},
{
"name": "Vanessa",
"coins": 18,
"weapons": 1,
"otherItems": 5,
"color": "blue"
},
{
"name": "Sharon",
"coins": 9,
"weapons": 5,
"otherItems": 1,
"color": "pink"
},
{
"name": "Walter",
"coins": 9,
"weapons": 2,
"otherItems": 4,
"color": "white"
}
]
let result = data.reduce((a,c)=> ({
coins: a.coins + c.coins,
weapons: a.weapons + c.weapons,
otherItems: a.otherItems + c.otherItems })
)
console.log(result);
You could take an array of wanted keys for the sums and create an object for the sums and add the wanted values.
const
data = [{ name: "Dave", coins: 14, weapons: 2, otherItems: 3, color: "red" }, { name: "Vanessa", coins: 18, weapons: 1, otherItems: 5, color: "blue" }, { name: "Sharon", coins: 9, weapons: 5, otherItems: 1, color: "pink" }, { name: "Walter", coins: 9, weapons: 2, otherItems: 4, color: "white" }],
keys = ['coins', 'weapons', 'otherItems'],
sums = data.reduce(
(r, o) => (keys.forEach(k => r[k] += o[k]), r),
Object.fromEntries(keys.map(k => [k, 0]))
);
console.log(sums);
You can use Array.prototype.reduce for this.
To make it a little bit more flexible and dynamic, make a Set of keys you want to get a count of.
Then go through each key in the Set and if that key is in the obj, sum it up in an accumulator object in the reduce callback:
const data = [{"name":"Dave","coins":14,"weapons":2,"otherItems":3,"color":"red"},{"name":"Vanessa","coins":18,"weapons":1,"otherItems":5,"color":"blue"},{"name":"Sharon","coins":9,"weapons":5,"otherItems":1,"color":"pink"},{"name":"Walter","coins":9,"weapons":2,"otherItems":4,"color":"white"}]
//Keys to count
const keys = new Set(["coins", "weapons", "otherItems"]);
const count = data.reduce((acc, obj) => {
const objKeys = keys.forEach(key => {
if (obj.hasOwnProperty(key)) {
acc[key] = (acc[key] || 0) + obj[key];
}
});
return acc;
}, {});
console.log(count);
Your idea is right, you need to use reduce method. The problem is that you're summing two objects, not their properties. All you need to do is change the code to the following (to sum the coins):
data.reduce((first, last) => first.coins + last.coins, 0)
And following for weapons:
data.reduce((first, last) => first.weapons + last.weapons, 0)
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)