Convert multiple objects in array into an array - javascript

I want to convert this:
var x = [{ order_id: 10,
product_id: 5,
product_after_price: 50 },
{ order_id: 10,
product_id: 6,
product_after_price: 50 }]
Into this:
[[10, 5, 50], [10, 6, 50]]
I tried .map() function but it just doesn't work. Any help would be appreciated, thank you!

If you want to ensure the order of the values in the array across different JS engines, you can create an array of property keys (order), and iterate it to get the values in the requested order.
const order = ['order_id', 'product_id', 'product_after_price'];
const x = [{"order_id":10,"product_id":5,"product_after_price":50},{"order_id":10,"product_id":6,"product_after_price":50}];
const result = x.map((o) => order.map((key) => o[key]));
console.log(result);

Without considering order, simply use map
arr.map( s => Object.values(s) )
But you need to specify the order first
var order = ["order_id", "product_id", "product_after_price"];
then use map
var output = arr.map( function(item){
return order.reduce( function(a,c){
a.push( item[c] );
return a;
}, []);
})
Demo
var order = ["order_id", "product_id", "product_after_price"];
var x = [{
order_id: 10,
product_id: 5,
product_after_price: 50
},
{
order_id: 10,
product_id: 6,
product_after_price: 50
}
];
var output = x.map(function(item) {
return order.reduce(function(a, c) {
a.push( item[c] );
return a;
}, []);
});
console.log(output);

It is really the very simple question, it is my kind advice that you should refer javascript core functions first before post a question here.
var x = [{ order_id: 10,
product_id: 5,
product_after_price: 50 },
{ order_id: 10,
product_id: 6,
product_after_price: 50 }]
var arrValues = []
for(var index=0; index< x.length; index++){
if(!!x[index]){
arrValues.push(Object.values(x[index]));
}
}
console.log(arrValues);

Related

I want to change the structure of my array

I need to modify a data which is coming from API. The data is coming in the form of array of objects.
const crosses = [
{
fatherLineId: 8,
fatherLineName: "2ART18-0008",
id: 54,
motherLineId: 5,
motherLineName: "2ART18-0005",
},
{
fatherLineId: 3
fatherLineName: "2ART18-0003",
id: 55,
motherLineId: 5,
motherLineName: "2ART18-0005",
}
]
I want my data to be restructured in the form of:
const resultantArr = [
{
enteryNumber: 1,
ParentName: "2ART18-0008"
},
{
entryNumber: 2,
ParentName: "2ART18-0005",
},
{
entryNumber: 3,
ParentName: "2ART18-0003"
},
and so on ...
];
Here the parentName property will have motherLineName values and fatherLineName values in the order.
When you get the result of the api call, loop through it and map the data toy our custom object, I can't provide a complete example based on your question but something like this:
You may also need to parse the apiresult into json using JSON.parse()
var resultantArr = [];
for(var i = 0; i < apiresult.length; i++)
{
resultantArr.push({"enteryNumber" : i + 1 , "ParentName" : apiresult[i].fatherLineName });
}
Loop over the array and push two separate objects into an output array. And keep a record of each object entryname that you increment by two at the end of each iteration.
const crosses=[{fatherLineId:8,fatherLineName:"2ART18-0008",id:54,motherLineId:5,motherLineName:"2ART18-0005"},{fatherLineId:3,fatherLineName:"2ART18-0003",id:55,motherLineId:5,motherLineName:"2ART18-0005"}];
const out = [];
let count = 1;
crosses.forEach(obj => {
const { fatherLineName, motherLineName } = obj;
out.push({
entryNumber: count,
parentName: fatherLineName
});
out.push({
entryNumber: count + 1,
parentName: motherLineName
});
count = count + 2;
});
console.log(out);
Hope it helps you... 🙂
const crosses = [
{
fatherLineId: 8,
fatherLineName: "2ART18-0008",
id: 54,
motherLineId: 5,
motherLineName: "2ART18-0005",
},
{
fatherLineId: 3,
fatherLineName: "2ART18-0003",
id: 55,
motherLineId: 5,
motherLineName: "2ART18-0005",
}
];
var result = [];
var count = 1;
crosses.forEach(cross => {
result.push({
parentName: cross.fatherLineName,
entryNumber: count++,
}),
result.push({ parentName: cross.motherLineName,
entryNumber: count++,
})
});
result

How can we print value from an array if two array matches with some value in JavaScript?

I have to compare two array of objects and check if the same item includes in the other array.
const array1 = [
{ item: "orange", id: 11 },
{ item: "apple", id: 12 },
];
const array2 = [10, 11, 12];
If I am checking with a value from array2 in array1.How can I get output like below when mapping array2?
Item does'nt exists
orange
apple
Here's a way using Map, though with a bit of tweaking it could use a normal object instead of Map. The map indexes the items in array1 by id and then allows you to look for the item in the map (using has() or get()); if it doesn't exist you can fall back to the default string. ?? is the nullish coalescing operator and it allows you to give a term for the expression should the value before ?? be null or undefined.
const array1 = [{ item: "orange", id: 11 }, { item: "apple", id: 12 }];
const array2 = [10, 11, 12];
const default_string = "Item does'nt exists";
const array1_map = new Map(array1.map((o) => [o.id, o]));
const res = array2.map( (id) => array1_map.get(id)?.item ?? default_string );
console.log(res);
Try this
const array1 = [{
item: 'orange',
id: 11
}, {
item: 'apple',
id: 12
}]
const array2 = [10, 11, 12]
for (const x of array2) {
//find element from array
const searchElem = array1.find((item) => item.id == x)
if (searchElem) {
console.log(searchElem.item + " for " + x)
} else {
console.log("Item doesn't exists for", x)
}
}
You can easily achieve this result using map and find
const array1 = [
{ item: "orange", id: 11 },
{ item: "apple", id: 12 },
];
const array2 = [10, 11, 12];
const result = array2.map((id) => {
const itemFound = array1.find((o) => o.id === id);
if (itemFound) return `${itemFound.item} for ${itemFound.id}`;
else return `Item does'nt exists for 10`;
});
console.log(result);
The easiest way to get common items by comparing two array in JavaScript is using filter() and includes() array functions.
For example:
const array1 = [
{ item: "orange", id: 11 },
{ item: "apple", id: 12 },
];
const array2 = [10, 11, 12];
const matchedArray = array1.filter((item) => array2.includes(item.id));
console.log(matchedArray);
We don't need to use for loop, forEach, map and find functions.
Try this code I think it will solve your problem
I have written some comments on javascript code it may help you.
const array1=[{item:'orange', id:11},{item:'apple', id:12}]
const array2=[10,11,12]
function removeDuplicates(array, matchKey) {
return array.filter((value, index) => {
return array.indexOf(array.find(value_1 => value_1[matchKey] == value[matchKey])) == index
});
}
// send "id" parameter if you want to filter array by id
// ex: removeDuplicates(array1, 'id')
const filteredArray1 = removeDuplicates(array1, 'item');
array2.forEach(id => {
let foundItem = array1.find(itemObj => itemObj.id == id);
if(foundItem == null) {
console.log(`Item doesn't exists for ${id}`);
}else {
console.log(`${foundItem.item} for ${id}`);
}
});
If I understand the question correctly what you want to do is confirm if an object with a certain property exists in Array 1 for each element in Array 2.
If you want to check each and see if it exists you can do this:
const fruits = [
{item: 'orange', id: 11},{item: 'apple', id: 12}
]
const fruitIds = fruits.map((fruit) => fruit.id);
const ids = [10, 11, 12]
ids.forEach((id) => {
console.log(`${id} exists in fruits: ` + fruitIds.includes(id))
})
Or if you wish to check if there is a fruit for each ID in the array and you only care about true / false if all exist or not then you can do:
const fruits = [
{item: 'orange', id: 11},
{item: 'apple', id: 12}
]
const fruitIds = fruits.map((fruit) => fruit.id).sort();
const ids = [10, 11, 12];
console.log("There is a fruit for each ID in ID array: ", JSON.stringify(ids) === JSON.stringify(fruitIds))
If this does not answer your question then please edit and try to make your question clearer and I'll do the same with my answer.
Note that the last snippet is just one way to compare arrays or objects in JavaScript.

How to build an inverted map from a one-to-many list with functional programming in JavaScript?

Just to clarify this is what I mean by "inverted map":
const foo =
{ "a": 10
, "b": 20
};
const foo_inverted =
{ "10": "a"
, "20": "b"
};
I have this object representing a file:
const file =
{ id: 100
, tags: [20, 30]
};
Given a list of files I need to build a map that allows me to find all files with a given tag.
From this:
const files =
[ { id: 100
, tags: [20, 30]
}
, { id: 200
, tags: [20, 40]
}
];
To that:
{ "20": { "100": 1, "200": 1 }
, "30": { "100": 1 }
, "40": { "200": 1 }
}
I ended up with this code which does the job:
const tag_file = (tag_id, file_id) => ({[tag_id]: {[file_id]: 1}});
const mergeDeepAll = reduce(mergeDeepRight, {});
const tag_map = compose(mergeDeepAll, lift(tag_file));
const tags_map = compose(mergeDeepAll, map(({id, tags}) => tag_map(tags, [id])));
tags_map(files);
//=> { "20": { "100": 1, "200": 1 }
//=> , "30": { "100": 1 }
//=> , "40": { "200": 1 }
//=> }
Question: am I missing any functional programming concepts that would have allowed me to express this better?
Create an a function that generates pairs [tag, id] for each object, using a Array.map() (idByTags). Using R.chain convert all objects to such pairs and flatten them. Group by the tag (R.head), and then map the object (R.mapObjIndexed) and count by the id (R.last):
const { pipe, chain, groupBy, head, mapObjIndexed, countBy, last } = R
const idByTags = ({ id, tags }) => tags.map(tag => [tag, id])
const fn = pipe(
chain(idByTags),
groupBy(head),
mapObjIndexed(countBy(last))
)
const files = [{"id":100,"tags":[20,30]},{"id":200,"tags":[20,40]}]
const result = fn(files)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.0/ramda.js"></script>
not sure why you would need ramda, can do it with reduce and forEach
const files = [{
id: 100,
tags: [20, 30]
}, {
id: 200,
tags: [20, 40]
}];
// loop over the array to make an object
const result = files.reduce((obj, file) => {
// loop over the tags
file.tags.forEach(
tag =>
obj[tag] ? // have we seen the tag?
obj[tag].push(file.id) : // yes
obj[tag] = [file.id] // no
)
return obj // return the object for reduce
}, {})
console.log(result)
AFTER YOUR EDIT
const files = [{
id: 100,
tags: [20, 30]
}, {
id: 200,
tags: [20, 40]
}];
// loop over the array to make an object
const result = files.reduce((obj, file) => {
// loop over the tags
file.tags.forEach(
tag => {
obj[tag] = obj[tag] || {} // have we seen the tag?
obj[tag][file.id] = 1 //
})
return obj // return the object for reduce
}, {})
console.log(result)

Change index in array.map

I have a variable of the form:
var data=[
{
start:22,
end: 8
},
{
start:60,
end: 43
},
{
start: 35,
end: 55
},
{
start:25,
end:40
}
];
I want to map it to look like this
var newData = { 22:8, 60:43, 35:55, 25:40};
Is this possible? I mainly just want to use the start numbers as a key to access the end numbers without using search. I have tried to do this:
var mapData = data.map(function(data){
var x = {};
x[data.start]=data.end;
return x;
});
but it gives:
0
:
{22: 8}
1
:
{60: 43}
2
:
{35: 55}
3
:
{25: 40}
which means i have to use 0, 1,2, 3 as indices.
Only Array#map does not work in this case, because without post processing, you get a single array with objects. You need to combine all objects into a single object.
With Object.assign and spread syntax ..., you get a single array with all properties from the objects in the array.
var data = [{ start: 22, end: 8 }, { start: 60, end: 43 }, { start: 35, end: 55 }, { start: 25, end: 40 }],
result = Object.assign(...data.map(({ start, end }) => ({ [start]: end })));
console.log(result);
You can use array.reduce:
var data=[
{
start:22,
end: 8
},
{
start:60,
end: 43
},
{
start: 35,
end: 55
},
{
start:25,
end:40
}
];
var res = data.reduce((m, o) => {
m[o.start] = o.end;
return m;
}, {});
console.log(res);

sort 2 array with the values of one of them in javascript

i have two array, lets say
priceArray= [1,5,3,7]
userIdArray=[11, 52, 41, 5]
i need to sort the priceArray, so that the userIdArray will be also sorted.
for example the output should be:
priceArray= [1,3,5,7]
userIdArray=[11, 41, 52, 5]
any ideas how to do it?
i am writing my server in NodeJS
Taken from Sorting with map and adapted for the userIdArray:
// the array to be sorted
var priceArray = [1, 5, 3, 7],
userIdArray = [11, 52, 41, 5];
// temporary array holds objects with position and sort-value
var mapped = priceArray.map(function (el, i) {
return { index: i, value: el };
});
// sorting the mapped array containing the reduced values
mapped.sort(function (a, b) {
return a.value - b.value;
});
// container for the resulting order
var resultPrice = mapped.map(function (el) {
return priceArray[el.index];
});
var resultUser = mapped.map(function (el) {
return userIdArray[el.index];
});
document.write('<pre>' + JSON.stringify(resultPrice, 0, 4) + '</pre>');
document.write('<pre>' + JSON.stringify(resultUser, 0, 4) + '</pre>');
With proper data structure, as rrowland suggest, you might use this:
var data = [{
userId: 11, price: 1
}, {
userId: 52, price: 15
}, {
userId: 41, price: 13
}, {
userId: 5, price: 17
}];
data.sort(function (a, b) {
return a.price - b.price;
});
document.write('<pre>' + JSON.stringify(data, 0, 4) + '</pre>');
A bit shorter with ES6
var priceArray = [1, 5, 3, 7],
userIdArray = [11, 52, 41, 5],
temp = Array.from(priceArray.keys()).sort((a, b) => priceArray[a] - priceArray[b]);
priceArray = temp.map(i => priceArray[i]);
userIdArray = temp.map(i => userIdArray[i]);
console.log(priceArray);
console.log(userIdArray);
.as-console-wrapper { max-height: 100% !important; top: 0; }
It's hard to prescribe a better solution without knowing the whole use-case. That said, if you need these sorted by ID, it may make more sense to create a single array that contains user objects:
var users = [
{ id: 123, price: 25.00 },
{ id: 124, price: 50.00 }
];
users.sort(function(a, b) {
return a.id - b.id;
});
Or, if they don't need to be sorted, you can simply create a map of users by id:
var userPrices = {
123: 25.00,
124: 50.00
};
Building on Rrowland's answer, you can create the array of objects with a library like lodash:
var prices = [1, 5, 8, 2];
var userIds = [3, 5, 1, 9];
var pairs = _.zipWith(prices, userIds, function(p, u) {
return { price: p, userId: u };
});
This will give you an object like:
[
{ price: 1, userId: 3 },
{ price: 5, userId: 5 },
... etc
]
Then, for sorting, you can simply use a Javascript sort:
pairs.sort(function(p) { return p.price });
If you really need it as an array of userIds, you can get it back, after the sort:
var sortedUserId = pairs.map( function(p) { return p.userId });
// returns [ 3, 9, 5, 8 ];
I have seen a nice talk about making impossible state impossible. This covered the 2 arrays that are related but can go out of sync and better to use one array of objects that have 2 properties (as mentioned several times).
However; if you want to mutate both arrays and sort them the same way you can do the following:
//this will mutate both arrays passed into it
// you could return the arrays but then you need to do arr.slice(0).sort(...) instead
const sortSame = sortFn => (arrayToSort,arrayToSortSame) => {
const sortResults = [];
arrayToSort.sort(//will mutate the array
(a,b)=>{
const result = sortFn(a,b);
sortResults.push(result);
return result
}
);
arrayToSortSame.sort(()=>sortResults.shift());
return undefined;
}
const priceArray= [1,5,3,7];
const userIdArray=[11, 52, 41, 5];
const numSortSameAscending = sortSame((a,b)=>a-b);
numSortSameAscending(priceArray,userIdArray);
console.log(
priceArray,userIdArray
)
Even though the code in this answer may look simpler it is not the cheapest way to do it, as mapping is a cheaper operation than sorting (better to map 3 times and sort once then to sort twice) depending on the size of the arrays and how much the original array is out of order this way of sorting same may be very expensive.

Categories