I have a problem with figuring out how to find a common values in array of objects.
I have a big array of objects and every 2 objects have the same transactionHash. I need to find those objects that have the same values and put them in one array.
[
[{...otherData, transactionHash: 1}, {...otherData, transactionHash: 1}]
[{...otherData, transactionHash: 2}, {...otherData, , transactionHash: 2}]
]
I need it to be returned just like that!
I tried to reduce the array:
return yourData.reduce(function(curr, x) {
(curr[x[key]] = curr[x[key]] || []).push(x);
return curr;
})
And surprisingly I got most of the data back organized but somehow the last object wasn't in the right place but the object with the same `transactionHash` exists.
You forgot to pass an initial value for curr -
return yourData.reduce(function(curr, x) {
(curr[x[key]] = curr[x[key]] || []).push(x);
return curr;
}, {});
If you don't, then the first element of yourData will be used as the initial value.
Related
filteredArray is an array of variables So, I want to get a variable from it by searching in to it using a string and I want directly to use this variable in another code, can you help me?
const filteredArray = [livingRrooms, kitchens, ceilingsDesigns, bedroomsArray ];
// z is the string I get from a code that i have
const z = "livingRrooms kitchens ceilingsDesigns bedroomsArray";
function checkvar(cas) {
return z.includes(cas);
}
// as you can see next line is working just find
console.log(checkvar("kitchens"));
// this dosn't work because find use a srtict mode I need a way around it or anonther way
console.log(filteredArray.find(checkvar));
filteredArray is an array of variables
No, it's an array of values. Those values came from some variables, but there is no link from the array back to the variables where the values came from. If (for instance) both livingRooms and kitchens have the value 5, you have no way of knowing (at runtime) where either of the 5s in the array came from.
If you want to look for variables by name, use the variables to create object properties:
const items = {livingRooms, kitches, ceilingsDesigns/*...*/};
Then if you have x with the value "livingRooms", you can use items[x] to get the value for the livingRooms property from items.
I agree with what Sajeeb proposed
const inventory = [
{name: 'apples', quantity: 2},
{name: 'bananas', quantity: 0},
{name: 'cherries', quantity: 5}
];
function isCherries(fruit) {
return fruit.name === 'cherries';
}
console.log(inventory.find(isCherries));
// { name: 'cherries', quantity: 5 }
Hi I have following objects in an array and they appear like this:
[{col1:abc}
{col2:def}
{col1:ghi}]
What I want to do is if the same key is coming again I should overwrite it so it becomes
[{col1:ghi}
{col2:def}]
instead of appending another key value pair.
I am thinking of something like to overwrite
[col1:{col1:ghi}
col2:{col2:def}]
so that i can easily iterate over them in future.
Is there any way to put my keys in this way by using map or something similar?
Thank you
I'm going to assume all your objects look like the ones you provided in your question, i.e. they each are a single key-value pair (like {col1: "abc"})
We first need to loop over all the objects in your array, combining them into one large object. Since an object cannot have two identical keys, this has the effect of overwriting values associated with a key that occur earlier in the array with ones that associate with the same key, but occur later. This can be achieved with:
const unifiedObj = arr.reduce((acc, obj) => Object.assign(acc, obj), {})
reduce is a way of "looping" over the items in an array (well, not exactly, but you can think of it this way for now). Object.assign is a way to merge two objects. You should look these up in the MDN docs.
So now, if your original array looked like this:
[
{col1:"abc"}
{col2:"def"}
{col1:"ghi"}
]
The "unified" object will look like this:
{
col1: "ghi",
col2: "def"
}
Next, since you want an array of 'single key-value pair objects' as your final result, instead of this unified object, we're going to have to extract each key-value pair in the unified object into a new object, and collect all those new objects into an array. That's what this statement does.
const result = Object.keys(unifiedObj).map(k => ({k: unifiedObj[k]}))
Object.keys gives you all the keys of an object as an array. map transforms an array into another array, using the function supplied as its argument. Look these up too.
At the end, result will be an array that looks like this:
[
{ col1: "ghi" },
{ col2: "def" }
]
which seems to be what you wanted. Do note that the objects in the array might be in a different order from what you expect, i.e. the final array may also look like this:
[
{ col2: "def" },
{ col1: "ghi" }
]
This is quite an easy task! The explanation is in the code comments.
const arr = [{col1:'abc'},
{col2:'def'},
{col1:'ghi'}]
arr.forEach((item, index) => {
// get the key `col1`, `col2` etc. (only works if there is one key in the object!)
const key = Object.keys(item)[0]
// now check if the key was previously encountered
for (i = 0; i < index; i++) {
if (arr[i][key] !== undefined) {
// the same key was found in the already processed chunk of the array! Rewrite it with the latter value!
arr[i][key] = item
}
}
})
console.log(arr)
I think you probably want to produce a single object from your array of objects and retain all values for the same key, so that
[
{col1: 'abc'},
{col2: 'def'},
{col1: 'ghi'}
]
becomes
{
col1: ['abc', 'ghi'],
col2: ['def']
}
if that sounds right, then here's how to do it:
const arr = [
{col1: 'abc'},
{col2: 'def'},
{col1: 'ghi'}
];
const result = arr.reduce((memo, o) => {
Object.entries(o).forEach(([key, val]) => {
memo[key] = memo[key] || [];
memo[key].push(val);
});
return memo;
}, {});
console.log(result)
I am trying to use reduce within addKeyAndValue function on an array of objects with properties of key-value pairs, add within each object a new key-value pair and return that on a new array. The addKeyAndValue func receives three arguments the arr, the key and the value to be added together within each object in the array. I then use push within Reduce callback to push the objects in the array to the new array in the accumulator with the updated new key and value using the bracket notation.
var arr = [{name: 'Alonso'}, {name: 'James'}, {name: 'Chris'}, {name: 'Steve'}]
function addKeyAndValue(arr, key, value){
return arr.reduce(function(acc, nextValue, idx){
console.log(next);
acc.push(nextValue[key] = value);
return acc;
},[]);
}
and the expected result should be:
addKeyAndValue(arr, 'title', 'Instructor') //
[
{title: 'Instructor', name: 'Alonso'},
{title: 'Instructor', name: 'James'},
{title: 'Instructor', name: 'Chris'},
{title: 'Instructor', name: 'Steve'}
]
however, the results that I get in my Chrome dev console is:
(4) ["Instructor", "Instructor", "Instructor", "Instructor"]
0:"Instructor"
1:"Instructor"
2:"Instructor"
3:"Instructor"
length:4
__proto__:Array(0)
I am wondering why is the Value passed through nextValue[key] overriding the whole object and returning just as a string. When I try to just push the existing objects in the new array it works fine but when pushing the nextValue[key] it turns undefined and when doing the above nextValue[key] = value it overrides the objects resulting into a new array with just instructor strings. I am a bit confused since I was expecting a different result.
Using the bracket notations nextValue[key] on nextValue which is each object within the array being iterated by the callback in the reduce method I thought that would add a new key property in this case "title" with the assigned value of "instructor".
Any help would be appreciated, Thanks :).
Your push argument only results in the value being pushed, not the object. You can solve this with the comma operator if your really want this in one expression:
acc.push((nextValue[key] = value, nextValue));
But it may be more readable if you do it separately:
nextValue[key] = value;
acc.push(nextValue);
You are pushing the result of the assignment into the array, instead of the object.
Since the result nextValue[key] = value is value. Using acc.push(nextValue[key] = value); is like doing acc.push(value).
Since you want to update each object, use Array#map to iterate the array. Clone each object (to prevent mutating the original objects) using Object#assign, and add the property:
var arr = [{name: 'Alonso'}, {name: 'James'}, {name: 'Chris'}, {name: 'Steve'}];
function addKeyAndValue(arr, key, value){
return arr.map(function(obj){
var clone = Object.assign({}, obj);
clone[key] = value;
return clone;
});
}
var result = addKeyAndValue(arr, 'title', 'Instructor');
console.log(result);
The ES6 version
const arr = [{name: 'Alonso'}, {name: 'James'}, {name: 'Chris'}, {name: 'Steve'}];
function addKeyAndValue(arr, key, value){
return arr.map((obj) => Object.assign({ [key]: value }, obj));
}
const result = addKeyAndValue(arr, 'title', 'Instructor');
console.log(result);
I have an object that I need to transform into an array. Here is the code I have already:
for (var key in categoryData[p]) { // categorydata is an object, the "p" is because this is taking place in a loop (array of objects)
if (categoryData[p].hasOwnProperty(key)) {
var objToArray = $.map(categoryData[p], function(value, key) {
return [value];
});
}
}
Right now, this is returning:
0 : value
1 : value
2 : value
I want it to return:
Key : Value
Key : Value
Key : Value
But I haven't found a way to do this with my data. Any direction would be greatly appreciated!
Edit: Adding more information:
I want to sort from the highest to lowest value. For clarification, I want the data to look like this:
(key) (object)
"ABC" : 8
"DEF" : 7
"GHI" : 5
I am putting it into an array to begin with because I can't sort the values when they're in an object (as far as I know).
My data is fairly complex, in a CSV file, but the idea of it is:
ABC, DEF, GHI
8 , 7 , 5
Associative arrays aren't a thing in javascript. You can either have arrays denoted by [] with 0 based numeric indices, or objects denoted by {} that can store key-value pairs. The latter construct can be used as replacement to associative arrays (ie add arbitrary keys and values to it), but they cannot be treated like arrays.
What you want in this case is what you already have - a key/value store, except it's called an object.
edit
If you just want to sort the data regardless of datatypes
You can split your object into multiple objects with a single key-value pair, then create an array from these objects and sort them any way you like using Array.sort(). Here's a quick example of splitting your provided data into objects:
var originalData = {
"ABC" : 8,
"DEF" : 7,
"GHI" : 5,
},
sortableArray = [];
for (key in originalData) {
sortableArray.push({
"key" : key,
"value" : originalData[key]
});
}
This creates a new object and appends it to our sortable [] array. To sort it according to its original value, you need to supply a comparator function that accesses the value property of the objects.
sortableArray.sort(function(a,b) {
return a.value - b.value;
});
This should return an array of objects ordered by the value property of each object in ascending order. Simply switch a and b around to get a descending order sort.
Hope this helps!
The best approach to sort your data is to map your object into an array to look like this:
[
{
"key": someKey
"value": someValue
},
{
"key": someOtherKey
"value": someOtherValue
},
//...
]
using this code:
var objToArray = $.map(categoryData[p], function(value, key) {
return {"key": key, "value": value};
});
And then sort it using this code:
objToArray.sort(function(a, b) {
// if the values are numbers (otherwise you have to change this to addapt to your dataType)
return b.value - a.value; // to sort from highest to lowest or a.value - b.value to sort from lowest to highest
});
And then you can use it like:
objToArray[0].key; // to get the key of the first item
objToArray[3].value; // to get the value of the 4-th item
// ...
You can loop through them as well (for(var i = 0; i < objToArray.length; i++)...).
In ES6, Object.entries(a).sort((a, b) => a[1] < b[1] )
This will give you something like this
[
["ABC", 8]
["DEF", 7]
["GHI", 5]
]
the .entries step gives you the list of pairs and the .sort step sorts them by their second value
I have two arrays. The first one is just a list of some numbers, say, magicNumbers = [1,2,3,15,33]. The second one is an array of objects, all having a property magic, like that: magicObjects = [ { 'magic': 1 }, {'magic: 2}, {'magic': 15} ]
I need to create a new array, containing objects from magicObject, in the same order as value of magic property is in the magicNumbers array, and those places from magicNumbers that that do not have a corresponding object in magicObjects should be filled with null. In our example, this should give:
[ { 'magic': 1 }, {'magic: 2}, null, {'magic': 15}, null ]
It's quite easy to implement it in a straightforward manner with _.map() and _.find():
_.map(magicNumbers,
function(num) {
return _.find(magicObjects,
function(v) { return v.magic == num }
) || null;
});
Any ideas how do it properly in a javascript-way, with underscore.js, or maybe just more effective?
Usually this is done by populating a map id: object and fetching objects from the map as you go. So you get N+M performance instead of N*M:
console.info=function(x){document.write('<pre>'+JSON.stringify(x,0,3)+'</pre>')}
//--
magicNumbers = [1,2,3,15,33];
magicObjects = [ { 'magic': 1 }, {'magic': 2}, {'magic': 15} ];
var mapping = {};
magicObjects.forEach(o => mapping[o.magic] = o);
var result = magicNumbers.map(n => mapping[n] || null);
console.info(result);