Get first array objects in every second arrays index - javascript

Get first array objects in every second arrays index . Is it possible to get like this given expected output or not possible, we can use for or any other method in JavaScript This is the Two arrays:
let First = [
{lesson: 1},
{lesson: 2},
{lesson: 3}
]
# let Second = [
{
name: "John",
age : 26,
lesson: 1
},
{
name: "Ken",
age : 40,
lesson: 2
},
{
name: "William",
age : 18,
lesson: 3
}
]
Expected output
{
name: "John",
age : 26,
lesson: 1,
lesson: 2,
lesson: 3
},
{
name: "Ken",
age : 40,
lesson: 1,
lesson: 2,
lesson: 3
},
{
name: "William",
age : 18,
lesson: 1,
lesson: 2,
lesson: 3
},
]

you can't have multiple key with différent value in a object but you can do that if you want :
const persons = [{
name: "John",
age : 26,
lesson: [1, 2, 3],
},
{
name: "Ken",
age : 40,
lesson: [1, 2, 3],
},
{
name: "William",
age : 18,
lesson: [1, 2, 3],
},
]
And with code :
for (let i = 0; i < second.length; i++) {
second[i]["lesson"] = [1, 2, 3]
}

Related

using map with filter array JavaScript

i have a json and need to extract data to array.
const data = [{
"week": 1,
"lost": 10,
"recovery_timespan": [{
"week": 2,
"count": 1
}, {
"week": 3,
"count": 0
}],
"netLost": 10,
"netReturned": 20
}, {
"week": 2,
"lost": 7,
"recovery_timespan": [{
"week": 3,
"count": 1
}],
"netLost": 30,
"netReturned": 200
}, {
"week": 3,
"lost": 8,
"recovery_timespan":"",
"netLost": 50,
"netReturned": 40
}];
Expected output: lost,count in recovery_timespan,netLost , netReturned.
[ [ 10, 1, 0, 10, 20 ], [ 7, 1, 30, 200 ], [ 8, 50, 40 ] ]
As you can see expected output, last recovery_timespan does not contain any data and it just shows as "".so i need to ignore it.
My approach:
const result = data.map(({lost, recovery_timespan,netLost,netReturned}) => [
lost,
...recovery_timespan.map(({count}) => count),
netLost,netReturned
]);
My code breaks when "recovery_timespan" is "". How can i add a filter along with map to filter that part and make my code work?
It's just a matter of checking if it's string or not, but you can short circuit
const result = data.map(({lost, recovery_timespan,netLost,netReturned}) => [
lost,
...(recovery_timespan || []).map(({count}) => count),
netLost,netReturned
]);

I need to create a function that returns a plain javascript string that is indexed by 'name', and contains all the 'props'

My code seems to be right, but it isn't returning a ':' but a ',' at certain places of the Json result. please see desired result in the code comments.
I also don't like the "replaces" I coded to remove the array's brackets from the Json expression and I shouldn't modify the JSON string. Is there a more elegant way to do it?
// JSON Object
var items = [
{
name: "item 1",
id: 2,
props: {
a: "a prop1",
b: "b prop1",
},
values: [1, 2, 3],
},
{
name: "item 2",
id: 3,
props: {
a: "a prop2",
b: "b prop2",
},
values: [6, 1, 2, 3, 4],
},
{
name: "item 3",
id: 4,
props: {
a: "a prop3",
c: "c prop3",
},
values: [10, 1, 2, 3, 4, 5],
},
];
export function getObject(items) {
var arr = [];
for(var i in items){
arr.push(items[i].name);
arr.push(items[i].props);
}
var myJSON = JSON.stringify(arr).toString();
var test = myJSON.replace("[","{").replace("]","}"); // I couldn't find another way to extract the array data from the array brackets.
var test2 = JSON.stringify(test);
// test2 is returning: "{\"item 1\",{\"a\":\"a prop1\",\"b\":\"b prop1\"},\"item 2\",{\"a\":\"a prop2\",\"b\":\"b prop2\"},\"item 3\",{\"a\":\"a prop3\",\"c\":\"c prop3\"}}"
// but it's expected: "{\"item 1\":{\"a\":\"a prop1\",\"b\":\"b prop1\"},\"item 2\":{\"a\":\"a prop2\",\"b\":\"b prop2\"},\"item 3\":{\"a\":\"a prop3\",\"c\":\"c prop3\"}}"
return test2;
}
Use .map to transform each item into an object, which has one property, whose key is the item.name, and value is the item.props object:
const getObject = items => items.map(item => ({ [item.name]: item.props }));
// JSON Object
var items = [{
name: "item 1",
id: 2,
props: {
a: "a prop1",
b: "b prop1",
},
values: [1, 2, 3],
},
{
name: "item 2",
id: 3,
props: {
a: "a prop2",
b: "b prop2",
},
values: [6, 1, 2, 3, 4],
},
{
name: "item 3",
id: 4,
props: {
a: "a prop3",
c: "c prop3",
},
values: [10, 1, 2, 3, 4, 5],
},
];
console.log(getObject(items));
If you actually need a JSON string and not an object, then put JSON.stringify around it. (remember: There's no such thing as a "JSON Object".)
const getObject = items => JSON.stringify(items.map(item => ({ [item.name]: item.props })));
// JSON Object
var items = [{
name: "item 1",
id: 2,
props: {
a: "a prop1",
b: "b prop1",
},
values: [1, 2, 3],
},
{
name: "item 2",
id: 3,
props: {
a: "a prop2",
b: "b prop2",
},
values: [6, 1, 2, 3, 4],
},
{
name: "item 3",
id: 4,
props: {
a: "a prop3",
c: "c prop3",
},
values: [10, 1, 2, 3, 4, 5],
},
];
console.log(getObject(items));

Organizing an object to create keys when needed and/or push different attribute to value pair array

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);

Use dictionary to filter javascript data object

Say I have a filter:
filter = [ {key: "pl", value: 3}, {key: "sh", value: 2} ]
I want to filter the following javascript object with the above filter conditions:
var data = [
{title: "The Uncertainty of the Poet ",
pl: 3,
si: 2,
va: 3,
te: 0,
co: 0,
or: 4,
sh: 2,
po: 0,
li: 0,
ar: 5
},
{
title: "Direction",
pl: 4,
si: 3,
va: 1,
te: 3,
co: 0,
or: 3,
sh: 2,
po: 0,
li: 0,
ar: 5
}
...
]
I tried the following with no luck:
var result = data.filter(function(d){
for (item in filter) {
return d.key==d.value;
}
Just another potential option to check if the object meets all the criteria:
data.filter(function(obj) {
return filter.reduce(function(a, f) {
return a && (obj[f.key] === f.value);
}, true);
});
That will work without having to check for hasOwnProperty because of the use of reduce. If you wanted to check for if any of the filter conditions are true, you would change it to
data.filter(function(obj) {
return filter.reduce(function(a, f) {
return a || (obj[f.key] === f.value);
}, false);
});
You can do this way as well:
var filters = [{key: "pl", value: 3}, {key: "sh", value: 2}]
var data = [
{
title: "The Uncertainty of the Poet ",
pl: 2,
si: 2,
va: 3,
te: 0,
co: 0,
or: 4,
sh: 3,
po: 0,
li: 0,
ar: 5
},
{
title: "Direction",
pl: 3,
si: 3,
va: 1,
te: 3,
co: 0,
or: 3,
sh: 2,
po: 0,
li: 0,
ar: 5
}
]
var result = data.filter((item) => {
for(let i = 0; i < filters.length; ++i) {
let filter = filters[i];
if(item[filter.key] && item[filter.key] === filter.value) {
return true;
}
}
return false;
});
If you want it to match one or the other values, this will work:
match = [ {key: "pl", value: 3}, {key: "sh", value: 2} ]
var result = data.filter(function(d) {
return d.pl === match[0]['value'] || d.sh === match[1]['value']
})
I've changed the name of the array to match to avoid confusion.
You aren't going deep enough with your for in. It is looping over the array and not working with each object in the array
Can use Array#every() to make sure every object in filter array has match in the data object
// filter main data
var result = data.filter(function(dataObj){
// check if all proprties within filter array are a match
return filter.every(function(filterObj){
//compare value of property found in filterObject with value
return dataObj[filterObj.key] === filterObj.value
})
})
console.log(result)
<script>
var filter = [ {key: "pl", value: 2}, {key: "sh", value: 3} ]
var data = [{
title: "The Uncertainty of the Poet ",
pl: 2,
si: 2,
va: 3,
te: 0,
co: 0,
or: 4,
sh: 3,
po: 0,
li: 0,
ar: 5
},
{
title: "Direction",
pl: 4,
si: 3,
va: 1,
te: 3,
co: 0,
or: 3,
sh: 2,
po: 0,
li: 0,
ar: 5
}
]
</script>

Reduce method - cannot get two seperate results

I've got an array like that:
const arr = [
[{rivals: ['player1','player2'], winner: "player1", player1Scored: 2, player2Scored: 1}],
[{rivals: ['player1','player3'], winner: "none", player1Scored: 2, player3Scored: 2}],
[{rivals: ['player2','player3'], winner: "player3", player2Scored: 1, player3Scored: 3}],
[{rivals: ['player1','player4'], winner: "none", player1Scored: 1, player4Scored: 1}]
]
I need to count scored points of every player, so it'll look like that:
{player1Scored: 5, player2Scored: 2, player3Scored: 5, player4Scored:1}
I tried this:
let scoreResult = arr.reduce((result, {0: obj}) => {
obj.rivals.forEach(rival => result[`${rival}Scored`] = result[`${rival}Scored`] || 0);
obj.rivals.forEach(rival => result[`${rival}Scored`] += obj.player1Scored)
return result;
}, {});
My mistake is that I'm asigning points of one player to two of them but cannot solve that.
Thank you for your help
To answer the problem, you have nested arrays with a single object. You could take a destructuring with the array and take the firts item as object.
Then take the names from rivals array and add the scores.
const
array = [[{ rivals: ['player1', 'player2'], winner: "player1", player1Scored: 2, player2Scored: 1 }], [{ rivals: ['player1', 'player3'], winner: "none", player1Scored: 2, player3Scored: 2 }], [{ rivals: ['player2', 'player3'], winner: "player3", player2Scored: 1, player3Scored: 3 }], [{ rivals: ['player1', 'player4'], winner: "none", player1Scored: 1, player4Scored: 1 }]],
result = array.reduce((r, [o]) => {
o.rivals.forEach(k => r[k + 'Scored'] = (r[k + 'Scored'] || 0) + o[k + 'Scored']);
return r;
}, Object.create(null));
console.log(result);
try this
scores = {}
arr.map(s => s[0]).forEach(s => {
s.rivals.forEach(r => {
scores[r] = scores[r] || 0;
scores[r] += s[`${r}Scored`]
})
})

Categories

Resources