I have list object like below
0:""
1:""
3:"tag1"
4:"tag2
This is my question how to ignore empty value.I need a result like the below.
0:"tag1"
1:"tag2
Thanks for help me.
One naive solution could be:
const obj = {
0: "",
1: "",
2: "tag1",
3: "tag2"
};
const newObj = Object.fromEntries(
Object.entries(obj).filter(([k, v]) => v)
);
Object.entries turns an object into an array of keys and values.
For example
Object.entries(obj)
becomes
[
[
"0",
""
],
[
"1",
""
],
[
"2",
"tag1"
],
[
"3",
"tag2"
]
]
which is then filtered by whether the value is "truthy"
.filter(([k,v]) => v))
and finally turned back into an object
Object.fromEntries
If that is an array, you can use filter.
let o = ["","",,"tag1","tag2"];
let res = o.filter(Boolean); // or o.filter(x => x);
console.log(res);
To be more precise, you could use:
let res = o.filter(x => x !== '');
Related
I have the below object obj(coming as a JSON response):
var obj = {
0: {
note: 'test1',
id: 24759045,
createTimeStamp: '2022-08-01T17:05:36.750Z',
},
1: {
note: 'test2',
id: 24759045,
createTimeStamp: '2022-08-01T17:05:51.755Z',
},
note: 'test1',
id: 24759045,
createTimeStamp: '2022-08-01T17:05:36.750Z',
};
I only want the objects with numbers("0" , "1" .. so on) to be pushed in an array.
Below is what I am trying to do:
let items = [];
for (var prop in obj) {
items.push(obj[prop]);
}
console.log(items);
// expected output:
[
{
note: 'test1',
id: 24759045,
createTimeStamp: '2022-08-01T17:05:36.750Z',
},
{
note: 'test2',
id: 24759045,
createTimeStamp: '2022-08-01T17:05:51.755Z',
},
]
Any pointers would be highly appreciated.
A few things to consider here.
Are the numeric keys ordered?
Does the order matter?
Are the numeric keys an index of the item in the array?
Are there any gaps in the numeric keys?
First solution, assuming that the numeric keys are the index in the array.
const items = Object.keys(obj).reduce((acc, key) => {
const index = parseInt(key);
if (Number.isNaN(index)) {
return acc;
}
acc[index] = obj[key];
return acc;
}, []);
Second solution, assuming that order matters, but that the numeric keys are not guaranteed to be contiguous.
const items = Object.keys(obj)
.filter((key) => Number.isNaN(parseInt(key)) === false)
.sort()
.map((key) => obj[key]);
Keep in mind that Object.keys does not guarantee that the keys are ordered alpha-numerically. So if order matters, then you have to sort them.
Third solution, if order doesn't matter.
const items = Object.keys(obj)
.filter((key) => Number.isNaN(parseInt(key)) === false)
.map((key) => obj[key]);
var result = [];
var obj = {
"0": {
"note": "test1",
"id": 24759045,
"createTimeStamp": "2022-08-01T17:05:36.750Z"
},
"1": {
"note": "test2",
"id": 24759045,
"createTimeStamp": "2022-08-01T17:05:51.755Z"
},
"note": "test1",
"id": 24759045,
"createTimeStamp": "2022-08-01T17:05:36.750Z"
}
for (var i in obj)
result.push(obj[i]);
$('#result').html(JSON.stringify(result));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="result"></div>
You can achieve this by doing the following steps.
Copied your object below -->
var obj = {
"0": {
"note": "test1",
"id": 24759045,
"createTimeStamp": "2022-08-01T17:05:36.750Z"
},
"1": {
"note": "test2",
"id": 24759045,
"createTimeStamp": "2022-08-01T17:05:51.755Z"
},
"note": "test1",
"id": 24759045,
"createTimeStamp": "2022-08-01T17:05:36.750Z"
}
Created new js array -->
var result = [];
Code -->
for (var i in obj)
result.push(obj[i]);
Find the solution from link below as well --> :) :)
https://jsfiddle.net/kavinduxo/95qnpaed/
I think you'll need to get the keys of the object, filter out the non-numeric ones, then map each key to the obj[key]:
var obj={"0":{"note":"test1","id":24759045,
"createTimeStamp":"2022-08-01T17:05:36.750Z"},"1":{"note":"test2","id":24759045,
"createTimeStamp":"2022-08-01T17:05:51.755Z"},
"note":"test1","id":24759045,"createTimeStamp":"2022-08-01T17:05:36.750Z"};
console.log(
Object.keys(obj)
.filter((key) =>!Number.isNaN(parseInt(key)))
.map((key) => obj[key])
)
Let's consider I have the following plain object:
var numberedList = {
"1": "Text of 1",
"1.1": ["array of 1.1"],
"1.2": {
key: "object of 1.2"
},
"1.1.1": 999,
"1.2.1": true,
"1.2.2": function () {
return "function of 1.2.2";
},
"1.3": null,
"2": 2
}
I want to accomplish the following multidimensional array:
To easy explain myself:
[
["1",
[
[
[
"1.1",
[
"1.1.1"
]
]
],
[
[
"1.2",
[
"1.2.1",
"1.2.2"
]
],
],
"1.3"
]
],
"2"
]
Final array:
[
[
"Text of 1",
[
[
[
["array of 1.1"],
[
999
]
]
],
[
[
{
key: "object of 1.2"
},
[
true,
function()
{
return "function of 1.2.2";
}
]
],
],
null
]
],
2
]
Note that the deepest elements are not wrapped into an array.
How can I do a generic recursion function to accomplish this in pure vanilla js?
The main objective is to perform a tree of console.group() calls such as the console.groupEnd()would be also called on the end of each tree branch. It would be a bonus to help me to accomplish this also – given the object on the top execute these console calls.
Here is my solution,
var numberedList = { "1": "Text of 1", "1.1": ["array of 1.1"], "1.2": { key: "object of 1.2" }, "1.1.1": 999, "1.2.1": true, "1.2.2": function () { return "function of 1.2.2"; }, "1.3": null, "2": 2 }
function gen(numberedList) {
let result = Object.keys(numberedList).reduce((res, key) => {
let indexs = key.split(".");
let lastindex = indexs.pop()
indexs.reduce((res, i) => res[i], res)[lastindex] = [key]
return res
}, []);
result.shift(); // Removing first item, Becouse index count from 0;
return result
}
console.log(gen(numberedList))
You need to create a trimer function, to trim this result, for removing brackets ([])
First of all, in the future, please include your attempted code, or at least one relevant version of it, in the question. It's not a problem to refer to JSFiddle or the like for additional context, but the question should be complete enough without it.
Here I use a generic helpers, setPath, which takes a path such as ['foo', 0, 'bar', 'baz'], a new result, say, 'new result', and creates an updated copy of a nested object/array with the value at that path set to the new value:
setPath
(['foo', 1, 'bar', 'baz'])
("new result")
({foo: [{bar: {qux: 3}}, {bar: {qux: 5}}], corge: 8})
//=> {foo: [{bar: {qux: 3}}, {bar: {qux: 5, baz: "new result"}}], corge: 8}
// ^^^^^^^^^^^^^^^^^
(Here integers represent array indices and strings represent object keys.)
Then it's a simple matter of converting your input structure into an array of path-value objects, and reduce-ing that by calling setPath with each of them on a target array.
const setPath = ([p, ...ps]) => (v) => (o) =>
p == undefined ? v : Object .assign (
Array .isArray (o) || Number .isInteger (p) ? [] : {},
{...o, [p]: setPath (ps) (v) ((o || {}) [p])}
)
const nest = (o) =>
Object .entries (o) .map (
([k, v]) => [k .split ('.') .map (Number), v]
) .reduce ((a, [p, v]) => setPath (p) ([[v]]) (a), []) .slice (1)
const numberedList = {"1": "Text of 1", "1.1": ["array of 1.1"], "1.2": {key: "object of 1.2"}, "1.1.1": 999, "1.2.1": true, "1.2.2": function () {return "function of 1.2.2";}, "1.3": null, "2": 2}
console .log (nest (numberedList))
.as-console-wrapper {max-height: 100% !important; top: 0}
This isn't precisely the output you requested. But I don't make much sense out of that output. You might have to tweak a bit to get it exactly how you want.
I am struggeling a bit to merge nested arrays into a new object.
I have an array with nested objects in it. The objects contain an array. Now I want to merge the entries of this array into a new object and assign a value to it. For example "false". Please see the example.
Current Structure:
const arr = [
{
baa: "some",
foo: ["1", "2", "3"],
},
{
baa: "some",
foo: [
"4",
"5",
"6",
"7",
],
},
]
Target Structure: merge "foo" entries into object and assign value.
const obj = {
1: false,
2: false,
3: false,
4: false,
5: false,
6: false,
7: false,
};
Fetch the array foo and iterate over using forEach and get the value and make it a property, You can do this using reduce.
const arr = [
{
baa: "some",
foo: ["1", "2", "3"],
},
{
baa: "some",
foo: ["4", "5", "6", "7"],
},
];
const result = arr.reduce((acc, curr) => {
const { foo } = curr;
foo.forEach((el) => (acc[el] = false));
return acc;
}, {});
console.log(result);
More declarative answer:
const arr = [
{
baa: "some",
foo: ["1", "2", "3"],
},
{
baa: "some",
foo: ["4", "5", "6", "7"],
},
];
// Build `obj` from `arr`
const obj = Object.fromEntries(
arr.map(val => val.foo)
.flat()
.map(
key => [key, false]
)
)
console.log(obj)
Side note: not compatible with legacy browsers such as IE11, see coverage here: https://caniuse.com/mdn-javascript_builtins_object_fromentries
While the other answers are correct I find them so much harder to read than a simple double loop.
let result = {}
for(let obj of arr){
for(let innerArrElem of obj.foo){
result[innerArrElem] = false
}}
}}
function populate(arr, value) {
return arr.reduce((acc, element) => {
element.foo.forEach((f) => acc[f] = false);
return acc;
}, {})
}
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);
How to change nested object to array object by type in javascript.
Based on object key value type if its array/string
change the object to array as shown below in javascript
var ob1 = {
"list": [
"service",
"finance",
"s1.jpg"
],
"info": [
"details",
"mail",
"s2.jpg"
]
}
var ob2 = {
key1: "v1",
key2: "v2"
}
var result1=this.modifyObject(ob1);
var result2=this.modifyObject(ob2);
function modifyObject(ob){
const { field, value, id, ...fields } = ob;
const rest = Object.entries(fields)
.map(([field, value], id) => ({ field, value, id }));
const result = [...rest];
return result;
}
Expected Output,
// object type value is array
[
{field: "list", value: ["service","finance"], image: "s1.jpg", id:0},
{field: "info", value: ["details","mail"], image: "s2.jpg", id:1}
]
// object type value is string
[
{field:"key1", value:"v1", id:0 },
{field:"key2", value:"v2", id:1 }
]
You can grab the entires of your input object using Object.entries() and map each [key, value] pair to a new object. You can determine what type of object you want to return by checking whether the second value in the [key, value] pair array is an array (ie: checking if the value is an array) by using Array.isArray(). If it is an array, you can set the value to be the array, and the image to be the last element (obtained by using .pop(), if you don't want to modify the original object you can use slice instead). Otherwise, if the element is not an array, you can return an object which has an id property. The id property is based on the index of the object from the mapping function.
See example below:
const ob1 = { "list": [ "service", "finance", "s1.jpg" ], "info": [ "details", "mail", "s2.jpg" ] }; const ob2 = { key1: "v1", key2: "v2" };
const modifyObject = obj =>
Object.entries(obj).map(([field, value], id) =>
Array.isArray(value) ? {field, value, image: value.pop()}
: {field, value, id}
);
const result1 = modifyObject(ob1);
const result2 = modifyObject(ob2);
console.log(result1);
console.log(result2);
Note that this id property is based on the ordering of how Object.entries() obtains the key-value pairs from your object, so it may differ in older browsers (the newest JS spec specifies the ordering of how the [key, value] pairs are obtained using Object.entries, but older browsers may not follow this)
You can use the function Array.prototype.entries along with the function Array.prototype.reduce to build the desired output.
let ob1 = { "list": [ "service", "finance", "s1.jpg" ], "info": [ "details", "mail", "s2.jpg" ]},
ob2 = { key1: "v1", key2: "v2"};
function modifyObject(obj) {
return Object.entries(obj).reduce((r, [field, value], id) => {
let [image] = Array.isArray(value) ? value.slice(-1) : [];
let v = Array.isArray(value) ? value.slice(0, value.length - 1) : value;
return r.concat(Object.assign({id, [field]: v}, image ? {image} : {}));
}, []);
}
console.log(modifyObject(ob1));
console.log(modifyObject(ob2));