I have an array of json objects, like so:
[
{id: "81238651", secondary_id: "P2087N", count: "2"},
{id: "89581097", secondary_id: "P2087N", count: "2"}
]
The goal is to get something that can be pretty-printed on the screen or to a log, such as a final string that reads like:
'id: '81238651', secondary_id: "P2087N", count: "2"\n
id: '89581097', secondary_id: "P2087N", count: "2"'
While I can loop over the array and use JSON.stringify() to put something together I was wondering if there were more sophisticated tools / packages that can assist in destructuring and prettifying things?
Easy readable code:
const arr = [
{id: "81238651", secondary_id: "P2087N", count: "2"},
{id: "89581097", secondary_id: "P2087N", count: "2"}
]
let finalStr = '';
for(let obj of arr) {
Object.keys(obj).forEach(key => {
finalStr += String(key + ': ' + obj[key] + ', ');
});
finalStr += '\n';
}
console.log(finalStr);
This will format is out, can change out the pattern how you like.
const rawObjects = [
{id: "81238651", secondary_id: "P2087N", count: "2"},
{id: "89581097", secondary_id: "P2087N", count: "2"}
];
const formatted = rawObjects.map(o => Object.keys(o)
.reduce((a, v, i) => a + `${v}: ${o[v]}${(i<Object.keys(o).length-1)?', ' : ''}`, ''))
.join('\n');
console.log(formatted);
Related
i have to make a object from array then i can work with it letter.
i am trying this code it work's but output getting only last one
let datas = "team1 1, team2 2, team3 3";
let teamdata = datas.split(" ");
var myObj = (function () {
var result = { Tname: null, count: null };
datas.split(/\s*\,\s*/).forEach(function (el) {
var parts = el.split(/\s* \s*/);
result.Tname = parts[0];
result.count = parseInt(parts[1]);
});
return result;
})();
console.log(myObj);
output getting { Tname: 'team3', count: 3 }
need output
[{name: "team1", count: 1},
{name: "team2", count: 2},
{name: "team3", count: 3}]
Simply, You could do it with
String.split() and Array.map()
let datas = "team1 1, team2 2, team3 3";
let teamdata = datas.split(", "); // ['team1 1', 'team2 2', 'team3 3']
let result = teamdata.map(team=>({team:team.split(/\s+/)[0],count:+team.split(/\s+/)[1]}))
console.log(result);
expected output:
[{name: "team1", count: 1},
{name: "team2", count: 2},
{name: "team3", count: 3}]
i have to make a object
But you then claim that your expected output is an array, not an object:
[
{name: "team1", count: 1},
{name: "team2", count: 2},
{name: "team3", count: 3}
]
In that case, make an array and then .push() to that array within the loop:
var result = [];
datas.split(/\s*\,\s*/).forEach(function (el) {
var parts = el.split(/\s* \s*/);
result.push({
Tname: parts[0],
count: parseInt(parts[1])
});
});
return result;
This should work fine:
let datas = "team1 1, team2 2, team3 3";
var results = [];
var myObj = (function () {
var result = { Tname: null, count: null };
datas.split(/\s*\,\s*/).forEach(function (el) {
var parts = el.split(/\s* \s*/);
result.Tname = parts[0];
result.count = parseInt(parts[1]);
results.push(result);
});
return results;
})();
console.log(results)
The problem with your code was that you successfully splitted the string and converted it to the object but as you are expecting the result to be in the array you were not storing the object rather were rewriting the same object time and again.
Hello I am new to the site, and I have a problem with javascript that I do not know how to fix.
I have an array, which I want to turn into an object.
arr = [
{prefer: "sport_swimming", rating: "1"},
{prefer: "sport_running", rating: "5"},
{prefer: "sport_tennis", rating: "2"},
{prefer: "study_archeology", rating: "4"}];
obj = Object.assign({}, arr);
console.log(obj);
I want to get to something like this:
{
"sport": {
"swimming":"1",
"running":"5",
"tennis":"2"
},
"study":
{
"archeology":"4"
}
}
Using reduce you can look over the array and build an object using the keys you split off the property.
const arr = [
{prefer: "sport_swimming", rating: "1"},
{prefer: "sport_running", rating: "5"},
{prefer: "sport_tennis", rating: "2"},
{prefer: "study_archeology", rating: "4"}
];
const out = arr.reduce((acc, data) => {
const parts = data.prefer.split("_");
acc[parts[0]] = acc[parts[0]] || {};
acc[parts[0]][parts[1]] = data.rating;
return acc;
}, {});
console.log(out);
You can use reduce:
const arr = [
{ prefer: "sport_swimming", rating: "1" },
{ prefer: "sport_running", rating: "5" },
{ prefer: "sport_tennis", rating: "2" },
{ prefer: "study_archeology", rating: "4" }];
const result = arr.reduce((a, e) =>
([parent, child] = e.prefer.split('_'),
(a[parent] ??= {})[child] = e.rating,
a), {});
console.log(result);
I have an example array:
arr = [{id:1, count: 2}, {id: 2, count: 6}, {id: 2, count: 4}, {id: 1, count:4}]
I need transform it to include arrays with objects inside based on id:
[[{id:1, count: 2}, {id: 1, count:4}], [{id: 2, count: 6}, {id: 2, count: 4}]]
If I will have 3 different ids - then it will have 3 arrays inside and so on.
If you know any good solutions - let me know. Lodash could be ok as well.
You can use groupBy from lodash to get a map like this:
{
'1': [{id:1, count: 2}, {id: 1, count:4}],
'2': [{id: 2, count: 6}, {id: 2, count: 4}]]
}
Then you can transform it to an array using Object.values()
Essentially you need these two lines:
const groupedById = _.groupBy(items, item => item.id);
const result = Object.values(groupedById);
Pure JS, with reduce:
arr.reduce((acc, curr) => {
let existing = acc.findIndex(elem => elem.some(obj => obj.id === curr.id));
if (existing > -1) {
acc[existing].push(curr);
}
else {
acc[acc.length] = [curr]
}
return acc;
}, []);
As you mentioned in your question lodash solution could also work for you, then loadash has one out of the box method groupBy which can achieve your desired result.
import { groupBy } from "lodash";
const arr = [{id:1, count: 2}, {id: 2, count: 6}, {id: 2, count: 4}, {id: 1, count:4}]
const result = groupBy(arr, 'id');
console.log(result)
Working DEMO
#domenikk showed a really good example! Also, you could use Ramda instead of Lodash to have a point-free function =)
const arr = [
{id:1, count: 2},
{id: 2, count: 6},
{id: 2, count: 4},
{id: 1, count:4}
]
const groupById = R.compose(
R.values,
R.groupBy(R.prop('id'))
)
console.log(groupById(arr))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
This question already has answers here:
Javascript - sort array based on another array
(26 answers)
Closed 3 years ago.
I have an array that looks like this:
order = [ "foo", "bar", "baz" ];
This array contains the attribute values I would like to sort my array of objects by. I want to sort the data so that all the objects with name "foo" are first, then "bar", then "baz". My array of objects looks something like this:
data = [
{name: "foo", score: 8},
{name: "baz", score: 4},
{name: "baz", score: 9},
{name: "foo", score: 6},
{name: "bar", score: 9}
];
I want to outcome of the data order to look like this, the array is ordered by name but also by score desc when the names are the same:
sortedData = [
{name: "foo", score: 8},
{name: "foo", score: 6},
{name: "bar", score: 9},
{name: "baz", score: 9},
{name: "baz", score: 4}
];
Here is the code I have tried so far:
order.forEach(name => {
sortedData = [...this.data].sort(function(obj1, obj2) {
return (
-(obj1.name) || obj2.score < obj1.score
);
});
});
console.log(sortedData);
You can simply use sort and indexOf
let order = [ "foo", "bar", "baz" ];
let data = [
{name: "foo", score: 8},
{name: "baz", score: 4},
{name: "baz", score: 9},
{name: "foo", score: 6},
{name: "bar", score: 9}
];
let op = data.sort((a,b)=> (order.indexOf(a.name) - order.indexOf(b.name)) || b.score - a.score )
console.log(op)
Use the index to sort based on the order, to get index you can use Array#indexOf method. To sort based on the number just return the difference.
// extract object properties for comparing
// return difference of indexes to sort based on that
// in case indexes are same return difference of score(to sort element with same name)
data.sort(({ name: a, score: as }, { name: b ,score: bs}) => order.indexOf(a) - order.indexOf(b) || bs - as)
let order = ["foo", "bar", "baz"];
let data = [{
name: "foo",
score: 8
},
{
name: "baz",
score: 4
},
{
name: "baz",
score: 9
},
{
name: "foo",
score: 6
},
{
name: "bar",
score: 9
}
];
data.sort(({ name: a, score : as }, { name: b ,score:bs}) => order.indexOf(a) - order.indexOf(b) || bs - as)
console.log(data)
We can use the array indices in the order array for sorting.
Also using object destructuring assignment to get the object keys for comparison.
If the first comparison of name key results in equality of the two keys then going for the second criteria of the score key.
In my answer I did not mutate the original array, if that kind of behavior is needed you can check this solution:
const order = [ "foo", "bar", "baz" ];
const data = [
{name: "foo", score: 8},
{name: "baz", score: 4},
{name: "baz", score: 9},
{name: "foo", score: 6},
{name: "bar", score: 9}
];
function sortArray(data, order){
const sortedArr = Array.from(data).sort(({name: name1, score: score1},{name: name2, score: score2}) =>{
return name1 === name2 ? score2 - score1 : order.indexOf(name1) - order.indexOf(name2);
});
return sortedArr;
}
console.log("***Sorted Array***");
console.log(sortArray(data, order));
console.log("***Original Array***");
console.log(data);
I have an object containing an id as the key, and quantity as the value, e.g.;
let order = {1002: 2, 1010: 1}
I want to compare the order object with an array of products, e.g.:
let stock = [{name: "test", id: "1002", quantity: 100}, {name: "moreTest", id: "1010", quantity: 100}]
I want to reduce the quantity for each object in my stocks array, based on the according value in the stocks object, e.g.:
let newStock = [{name: "test", id: "1002", quantity: 98}, {name: "moreTest", id: "1010", quantity: 99}]
Here's a one-liner approach:
let newStock = stock.map(item => ({...item, quantity: item.quantity - (order[parseInt(item.id,10)] || 0)}))
BTW:
I think stock's id should be a number (or order needs to have a string key - I used parseInt but I don't think it's the best practice).
stock should be a map as well to prevent multiple stocks with the same id.
Here is a possible solution, very clear:
let order = {1002: 2, 1010: 1}
let stock = [{name: "test", id: "1002", quantity: 100}, {name: "moreTest", id: "1010", quantity: 100}]
stock.forEach(element => {
Object.keys(order).forEach(function(key) {
const quantityBought = order[key];
// == and not === because element.id is a string and key is a number
if (element.id == key) {
element.quantity -= quantityBought;
}
});
});
console.log(stock);
You can use Array.prototype.reduce here something Like this
let stock = [{name: "test", id: "1002", quantity: 100}, {name: "moreTest", id: "1010", quantity: 100}]
let order = {1002: 2, 1010: 1}
let result=stock.reduce((acc,value)=>{
value.quantity=value.quantity-order[value.id];
acc.push(value);
return acc;
},[])
console.log(result)
For reference look at array reduce function in mozilla docs