How to swap keys and values in an object? JS - javascript

Please tell me how to get such an array where id : newExcluded(key), and excluded :(newExcluded value )
const newExcluded = {1:true,6:false,3:false,4:true,7:true}
coonst fetchExcluded = [
{"id": 1,"excluded": true},
{"id": 6, "excluded": false},
{"id": 3, "excluded": false},
{"id": 4, "excluded": true},
{"id": 7, "excluded": true},
]

You can use a Object.entries to convert it to an array of arrays and Array.prototype.map to convert each inner array to an object with the required properties
const newExcluded = {1:true,6:false,3:false,4:true,7:true}
fetchExcluded = Object.entries(newExcluded).map(([id, excluded]) => ({ id, excluded }));
console.log(fetchExcluded);

Without using map.
Iterate over the Object.entries (this returns an array which is why we're using for/of), and assign the key/value of each property to a new object.
const obj = {1:true,6:false,3:false,4:true,7:true};
const output = {};
for (const [key, value] of Object.entries(obj)) {
output[key] = value;
}
console.log(output);

Related

how to use filter in javascript for an array of arrays object?

Currently I have an array with values:
var array1 = ['new_user', 'promotion']
What i need to do is filter and an object with this array1:
OBJc = [
{"id": 1, "array_": ['promotion', 'test1']},
{"id": 2, "array_": ['test444', 'test1']},
{"id": 3, "array_": ['new_user', 'test1']}
]
I need to filter this json based of if "array_" has any of the values in array1.
So the output would be:
[
{"id": 1, "array_": ['promotion', 'test1']},
{"id": 3, "array_": ['new_user', 'test1']}
]
const filtered = OBJc.filter(obj => obj.array_.some(array1.includes))
Or with es6 destructuring:
const filtered = OBJc.filter({ array_ } => array_.some(array1.includes))
Basically you check each array_ element to see if it's included in array 1, and keep only those who satisfy this condition.
You want to filter, so lets filter.
OBJc.filter()
Now, you want to return true when your property has some value right?
OBJc.filter(value => {
return value['array_'].includes(x)
})
But there are multiple ones, and you need to know if at least some those values are on your list
OBJc.filter(value => {
return array1.some(arrV => value['array_'].includes(arrV));
})
Or if you like one liners:
OBJc.filter(value => array1.some(arrV => value['array_'].includes(arrV)));
Here's the solution:
var array1 = ['new_user', 'promotion']
JSONstr = [
{"id": 1, "array_": ['promotion', 'test1']},
{"id": 2, "array_": ['test444', 'test1']},
{"id": 3, "array_": ['new_user', 'test1']}
]
const result = JSONstr.filter(obj => {
let found = false;
array1.forEach(elm => {
if (obj.array_.includes(elm)) {
found = true;
}
});
if (found) {
return true;
}
});
console.log(result);
Here's one way if you like playing with booleans.
const reduceTruth = (a, b) => a || b;
const matches = JSONstr.filter(element => {
return element.array_.map( x => array1.map(y => y == x).reduce(reduceTruth, false)).reduce(reduceTruth, false);
});

How to merge objects by value and change property type?

I have this array of objects
[ { "value": "1", "hobbies": 'netflix'},{ "value": "1", "hobbies": 'food'} ]
I want to:
Merge objects by value attribute
Change hobbies property to an array
Merge property values
The expected output
[ { "value": "1", "hobbies": ['netflix','food']}]
Using reduce comes in handy here as it helps you iterate over the array and keep an accumulator to store the data in each iteration.
I set the acc to be a JSON object (key-value pairs) where the key is the value attribute and the value is the resulting item with this value.
Along the way, if there is no item with the given key in the acc, we add the object as it is while setting hobbies as an array instead of a string.
Otherwise, if it does contain such an object, we add it's value to the existinghobbies list.
Finally, we take the values of the resulting object which gives the list of grouped objects.:
const arr = [
{ "value": "1", "hobbies": 'netflix'},
{ "value": "2", "hobbies": 'reading'},
{ "value": "1", "hobbies": 'food'},
];
const res = Object.values(
arr.reduce((acc,item) => {
const { value, hobbies } = item;
acc[value] = acc[value]
? { ...acc[value], hobbies: [...acc[value].hobbies, item.hobbies] }
: { ...item, hobbies: [hobbies] };
console.log(acc);
return acc;
}, {})
);
console.log(res);
You can use a forEach loop to iterate through the array.
var arr = [ { "value": "1", "hobbies": 'netflix'},{ "value": "1", "hobbies": 'food'} ];
var k = {};
var out = [];
arr.forEach(elm => {
if(typeof(k[elm.value]) == "undefined")
k[elm.value] = {value:elm.value, hobbies:[]};
k[elm.value].hobbies.push(elm.hobbies);
});
Object.keys(k).forEach(key => out.push(k[key]));
console.log(out);
You can use Array#reduce with an object to store the result for each value. On each iteration, if the current value does not exist as a key in the accumulator object, we create it and initialize the hobbies property as an empty array. Then, we add the current hobby to the object at that value. After the reduce operation, we use Object.values to get an array of all the resulting values.
const arr = [ { "value": "1", "hobbies": 'netflix'},{ "value": "1", "hobbies": 'food'} ];
const res = Object.values(
arr.reduce((acc,{value, hobbies})=>
((acc[value] = acc[value] || {value, hobbies: []}).hobbies.push(hobbies), acc),
{}));
console.log(res);

Filter unique objects in array based on timestamp condition

I have the following array:
let arr = [
{"id": 123, "lastUpdate": 1543229793},
{"id": 456, "lastUpdate": 1545269320},
{"id": 123, "lastUpdate": 1552184795}
]
I need to filter the array based on the same ID, but also check the "lastUpdate" timestamp and keep only the newer entries. The result should be:
[
{"id": 456, "lastUpdate": 1545269320},
{"id": 123, "lastUpdate": 1552184795}
]
I have tried the following:
arr = arr.filter((e, index, self) =>
index === self.findIndex((t) => (
t.id === intent.id && t.lastUpdate > e.lastUpdate
))
)
However, this filters everything for me and the resulting array is empty. I think something is wrong with the last part of above && t.lastUpdate > e.lastUpdate.
Many thanks for any tips!
Hi there if you are looking for a performant solution you can use an object :)
let arr = [{"id": 123,"lastUpdate": 1543229793},
{"id": 456,"lastUpdate": 1545269320},
{"id": 123, "lastUpdate": 1552184795}];
let newArr = {}
arr.forEach(el => {
if(!newArr[el.id] || newArr[el.id].lastUpdate < el.lastUpdate){
newArr[el.id] = el
}
})
console.log(Object.values(newArr));
You can achieve it by looking for items that don't have an item2 where the update was later
arr.filter(item =>
{ return !arr.some(item2 =>
item.id === item2.id && item.lastUpdate < item2.lastUpdate)
});
What that code does is :
For each item in the array it look if in the array there is an item with the same id where the lastUpdate is superior to its own.
If there is one it return true (Array.some returns a boolean).
We negate that value and use it to filter.
You could do it step by step by converting to a set, sorting then getting the first item for each id:
let arr = [
{"id": 123, "lastUpdate": 1543229793},
{"id": 456, "lastUpdate": 1545269320},
{"id": 123, "lastUpdate": 1552184795}
]
// Get the ids by making a set of ids and then converting to array
let ids = [ ...new Set(arr.map((e) => e.id)) ];
// Sort the original by lastUpdate descending
arr.sort((a, b) => b.lastUpdate - a.lastUpdate);
// Get array of first item from arr by id
let res = ids.map(id => arr.find((e) => e.id == id));
console.log(res);

convert array of objects into object of objects properties from array

I need to convert an array of objects into an object of objects properties from the array.
Here is an example of an array of objects
const array = [
{
book:5,
car: 6,
pc: 7
},
{
headphone: 9,
keyboard: 10
},
];
I need it to be converted to
const obj = {
book:5,
car: 6,
pc: 7,
headphone: 9,
keyboard: 10
};
I tried many ways but can't achieve the final result. Thanks in advance
You could spread the array as parameters (spread syntax ...) for Object.assign, which returns a single object.
const
array = [{ book: 5, car: 6, pc: 7 }, { headphone: 9, keyboard: 10 }],
object = Object.assign({}, ...array);
console.log(object);
You can use .reduce() and Object.assign() methods:
const array = [
{book:5, car: 6, pc: 7},
{headphone: 9, keyboard: 10},
];
const result = array.reduce((r, c) => Object.assign(r, c), {});
console.log(result);
You can also loop through the array using for loops. Using .reduce() and Object.assign() may not me that clear to understang what is happening for people that don't understand too much about Objects in js, but is definitively less code.
for(let i = 0; i < array.length; i++){
for (let key in array[i]) {
if (array[i].hasOwnProperty(key)) {
obj[key] = array[i][key];
}
}
}
How about
let obj = {}
for(let object of array) {
Object.assign(obj, object)
}
console.log(obj)

How to convert an Object {} to an Array [] of key-value pairs in JavaScript

I want to convert an object like this:
{"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0}
into an array of key-value pairs like this:
[[1,5],[2,7],[3,0],[4,0]...].
How can I convert an Object to an Array of key-value pairs in JavaScript?
You can use Object.keys() and map() to do this
var obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0}
var result = Object.keys(obj).map((key) => [Number(key), obj[key]]);
console.log(result);
The best way is to do:
var obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0}
var result = Object.entries(obj);
console.log(result);
Calling entries, as shown here, will return [key, value] pairs, as the caller requested.
Alternatively, you could call Object.values(obj), which would return only values.
Object.entries() returns an array whose elements are arrays corresponding to the enumerable property [key, value] pairs found directly upon object. The ordering of the properties is the same as that given by looping over the property values of the object manually.
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries#Description
The Object.entries function returns almost the exact output you're asking for, except the keys are strings instead of numbers.
const obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0};
console.log(Object.entries(obj));
If you need the keys to be numbers, you could map the result to a new array with a callback function that replaces the key in each pair with a number coerced from it.
const obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0};
const toNumericPairs = input => {
const entries = Object.entries(input);
return entries.map(entry => Object.assign(entry, { 0: +entry[0] }));
}
console.log(toNumericPairs(obj));
I use an arrow function and Object.assign for the map callback in the example above so that I can keep it in one instruction by leveraging the fact that Object.assign returns the object being assigned to, and a single instruction arrow function's return value is the result of the instruction.
This is equivalent to:
entry => {
entry[0] = +entry[0];
return entry;
}
As mentioned by #TravisClarke in the comments, the map function could be shortened to:
entry => [ +entry[0], entry[1] ]
However, that would create a new array for each key-value pair, instead of modifying the existing array in place, hence doubling the amount of key-value pair arrays created. While the original entries array is still accessible, it and its entries will not be garbage collected.
Now, even though using our in-place method still uses two arrays that hold the key-value pairs (the input and the output arrays), the total number of arrays only changes by one. The input and output arrays aren't actually filled with arrays, but rather references to arrays and those references take up a negligible amount of space in memory.
Modifying each key-value pair in-place results in a negligible amount of memory growth, but requires typing a few more characters.
Creating a new array for each key-value pair results in doubling the amount of memory required, but requires typing a few less characters.
You could go one step further and eliminate growth altogether by modifying the entries array in-place instead of mapping it to a new array:
const obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0};
const toNumericPairs = input => {
const entries = Object.entries(obj);
entries.forEach(entry => entry[0] = +entry[0]);
return entries;
}
console.log(toNumericPairs(obj));
To recap some of these answers now on 2018, where ES6 is the standard.
Starting with the object:
let const={"1":9,"2":8,"3":7,"4":6,"5":5,"6":4,"7":3,"8":2,"9":1,"10":0,"12":5};
Just blindly getting the values on an array, do not care of the keys:
const obj={"1":9,"2":8,"3":7,"4":6,"5":5,"6":4,"7":3,"8":2,"9":1,"10":0,"12":5};
console.log(Object.values(obj));
//[9,8,7,6,5,4,3,2,1,0,5]
Simple getting the pairs on an array:
const obj={"1":9,"2":8,"3":7,"4":6,"5":5,"6":4,"7":3,"8":2,"9":1,"10":0,"12":5};
console.log(Object.entries(obj));
//[["1",9],["2",8],["3",7],["4",6],["5",5],["6",4],["7",3],["8",2],["9",1],["10",0],["12",5]]
Same as previous, but with numeric keys on each pair:
const obj={"1":9,"2":8,"3":7,"4":6,"5":5,"6":4,"7":3,"8":2,"9":1,"10":0,"12":5};
console.log(Object.entries(obj).map(([k,v])=>[+k,v]));
//[[1,9],[2,8],[3,7],[4,6],[5,5],[6,4],[7,3],[8,2],[9,1],[10,0],[12,5]]
Using the object property as key for a new array (could create sparse arrays):
const obj={"1":9,"2":8,"3":7,"4":6,"5":5,"6":4,"7":3,"8":2,"9":1,"10":0,"12":5};
console.log(Object.entries(obj).reduce((ini,[k,v])=>(ini[k]=v,ini),[]));
//[undefined,9,8,7,6,5,4,3,2,1,0,undefined,5]
This last method, it could also reorganize the array order depending the value of keys. Sometimes this could be the desired behaviour (sometimes don't). But the advantage now is that the values are indexed on the correct array slot, essential and trivial to do searches on it.
Map instead of Array
Finally (not part of the original question, but for completeness), if you need to easy search using the key or the value, but you don't want sparse arrays, no duplicates and no reordering without the need to convert to numeric keys (even can access very complex keys), then array (or object) is not what you need. I will recommend Map instead:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map
let r=new Map(Object.entries(obj));
r.get("4"); //6
r.has(8); //true
In Ecmascript 6,
var obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0};
var res = Object.entries(obj);
console.log(res);
var obj = {
"1": 5,
"2": 7,
"3": 0,
"4": 0,
"5": 0,
"6": 0,
"7": 0,
"8": 0,
"9": 0,
"10": 0,
"11": 0,
"12": 0
};
var res = Object.entries(obj);
console.log(res);
Yet another solution if Object.entries won't work for you.
const obj = {
'1': 29,
'2': 42
};
const arr = Array.from(Object.keys(obj), k=>[`${k}`, obj[k]]);
console.log(arr);
Use Object.keys and Array#map methods.
var obj = {
"1": 5,
"2": 7,
"3": 0,
"4": 0,
"5": 0,
"6": 0,
"7": 0,
"8": 0,
"9": 0,
"10": 0,
"11": 0,
"12": 0
};
// get all object property names
var res = Object.keys(obj)
// iterate over them and generate the array
.map(function(k) {
// generate the array element
return [+k, obj[k]];
});
console.log(res);
Use Object.entries to get each element of Object in key & value format, then map through them like this:
var obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0}
var res = Object.entries(obj).map(([k, v]) => ([Number(k), v]));
console.log(res);
But, if you are certain that the keys will be in progressive order you can use Object.values and Array#map to do something like this:
var obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0};
// idx is the index, you can use any logic to increment it (starts from 0)
let result = Object.values(obj).map((e, idx) => ([++idx, e]));
console.log(result);
You can use Object.values([]), you might need this polyfill if you don't already:
const objectToValuesPolyfill = (object) => {
return Object.keys(object).map(key => object[key]);
};
Object.values = Object.values || objectToValuesPolyfill;
https://stackoverflow.com/a/54822153/846348
Then you can just do:
var object = {1: 'hello', 2: 'world'};
var array = Object.values(object);
Just remember that arrays in js can only use numerical keys so if you used something else in the object then those will become `0,1,2...x``
It can be useful to remove duplicates for example if you have a unique key.
var obj = {};
object[uniqueKey] = '...';
With lodash, in addition to the answer provided above, you can also have the key in the output array.
Without the object keys in the output array
for:
const array = _.values(obj);
If obj is the following:
{ “art”: { id: 1, title: “aaaa” }, “fiction”: { id: 22, title: “7777”} }
Then array will be:
[ { id: 1, title: “aaaa” }, { id: 22, title: “7777” } ]
With the object keys in the output array
If you write instead ('genre' is a string that you choose):
const array= _.map(obj, (val, id) => {
return { ...val, genre: key };
});
You will get:
[
{ id: 1, title: “aaaa” , genre: “art”},
{ id: 22, title: “7777”, genre: “fiction” }
]
If you are using lodash, it could be as simple as this:
var arr = _.values(obj);
var obj = { "1": 5, "2": 7, "3": 0, "4": 0, "5": 0, "6": 0, "7": 0, "8": 0, "9": 0, "10": 0, "11": 0, "12": 0 }
let objectKeys = Object.keys(obj);
let answer = objectKeys.map(value => {
return [value + ':' + obj[value]]
});
const persons = {
john: { age: 23, year:2010},
jack: { age: 22, year:2011},
jenny: { age: 21, year:2012}
}
const resultArray = Object.keys(persons).map(index => {
let person = persons[index];
return person;
});
//use this for not indexed object to change array
This is my solution, i have the same issue and its seems like this solution work for me.
yourObj = [].concat(yourObj);
or you can use Object.assign():
const obj = { 0: 1, 1: 2, 2: 3};
const arr = Object.assign([], obj);
console.log(arr)
// arr is [1, 2, 3]
Here is a "new" way with es6 using the spread operator in conjunction with Object.entries.
const data = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0};
const dataSpread = [...Object.entries(data)];
// data spread value is now:
[
[ '1', 5 ], [ '2', 7 ],
[ '3', 0 ], [ '4', 0 ],
[ '5', 0 ], [ '6', 0 ],
[ '7', 0 ], [ '8', 0 ],
[ '9', 0 ], [ '10', 0 ],
[ '11', 0 ], [ '12', 0 ]
]
you can use 3 methods convert object into array (reference for anyone not only for this question (3rd on is the most suitable,answer for this question)
Object.keys() ,Object.values(),andObject.entries()
examples for 3 methods
use Object.keys()
const text= {
quote: 'hello world',
author: 'unknown'
};
const propertyNames = Object.keys(text);
console.log(propertyNames);
result
[ 'quote', 'author' ]
use Object.values()
const propertyValues = Object.values(text);
console.log(propertyValues);
result
[ 'Hello world', 'unknown' ]
use Object.entires()
const propertyValues = Object.entires(text);
console.log(propertyValues);
result
[ [ 'quote', 'Hello world' ], [ 'author', 'unknown' ] ]
Use for in
var obj = { "10":5, "2":7, "3":0, "4":0, "5":0, "6":0, "7":0,
"8":0, "9":0, "10":0, "11":0, "12":0 };
var objectToArray = function(obj) {
var _arr = [];
for (var key in obj) {
_arr.push([key, obj[key]]);
}
return _arr;
}
console.log(objectToArray(obj));
Recursive convert object to array
function is_object(mixed_var) {
if (mixed_var instanceof Array) {
return false;
} else {
return (mixed_var !== null) && (typeof( mixed_var ) == 'object');
}
}
function objectToArray(obj) {
var array = [], tempObject;
for (var key in obj) {
tempObject = obj[key];
if (is_object(obj[key])) {
tempObject = objectToArray(obj[key]);
}
array[key] = tempObject;
}
return array;
}
We can change Number to String type for Key like below:
var obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0}
var result = Object.keys(obj).map(function(key) {
return [String(key), obj[key]];
});
console.log(result);
you can use _.castArray(obj).
example:
_.castArray({ 'a': 1 });
// => [{ 'a': 1 }]

Categories

Resources