Get a slice of a Javascript Associative Array? [duplicate] - javascript

This question already has answers here:
How to get a subset of a javascript object's properties
(36 answers)
Closed 6 years ago.
I have an associative array object in Javascript that I need only part of. With a regular array, I would just use slice to get the part I need, but obviously this won't work on an associative array. Is there any built in Javascript functions that I could use to return only part of this object? If not, what would be considered best practices for doing so? Thanks!

There's not going to be a good way to 'slice' the Object, no, but you could do this if you really had to:
var myFields = ['field1', 'field2', 'field3'];
var mySlice = {};
for (var i in myFields) {
var field = myFields[i];
mySlice[field] = myOriginal[field];
}

There is small function I use:
/**
* Slices the object. Note that returns a new spliced object,
* e.g. do not modifies original object. Also note that that sliced elements
* are sorted alphabetically by object property name.
*/
function slice(obj, start, end) {
var sliced = {};
var i = 0;
for (var k in obj) {
if (i >= start && i < end)
sliced[k] = obj[k];
i++;
}
return sliced;
}

I've created this gist that does exactly this. It returns a new object with only the arguments provided, and leaves the old object intact.
if(!Object.prototype.slice){
Object.prototype.slice = function(){
var returnObj = {};
for(var i = 0, j = arguments.length; i < j; i++){
if(this.hasOwnProperty(arguments[i])){
returnObj[arguments[i]] = this[arguments[i]];
}
}
return returnObj;
}
}
Usage:
var obj = { foo: 1, bar: 2 };
obj.slice('foo'); // => { foo: 1 }
obj.slice('bar'); // => { bar: 2 }
obj; // => { foo: 1, bar: 2 }

Related

How To Remove object from Javascript Object Array By Value? [duplicate]

This question already has answers here:
Remove Object from Array using JavaScript
(32 answers)
Closed 3 years ago.
I am having array of objects defined in javascript and would like to delete values based on object property.
I used below code :
var addedItems = [];
var item = {};
item["TId"] = "";
item["VNo"] = "";
item["IDate"] = "";
item["Rate"] = 22;
item["ItemId"] = 12;
item["Quantity"] = 1;
item["ItemTypeId"] = 3;
addedItems.push(item);
removeValueFromObjectByValue(addedItems,12);
function removeValueFromObjectByValue(jsonObject, value) {
jQuery.each(jsonObject, function (i, val) {
if (val.ItemId == value) // delete index
{
return;
delete jsonObject[i];
return;
}
});
}
Expected Result :
When I remove value, it should give me array with 0 elements.
Actual output :
When I remove value, I am getting array with 1 element and the element value is null.
You can use Object.values and splice. Inside the function create a new copy of the original array using JSON.parse & JSON.stringify so that original array does not get modified. Inside the forEach callback use Object.values which will give an array of values. Then use includes to check if this array created using Object.values contains the parameter passed in the function. If true then remove the element from the copied array using splice
var addedItems = [];
var item = {};
item["TId"] = "";
item["VNo"] = "";
item["IDate"] = "";
item["Rate"] = 22;
item["ItemId"] = 12;
item["Quantity"] = 1;
item["ItemTypeId"] = 3;
addedItems.push(item);
function removeValueFromObjectByValue(arr, num) {
let newArr = JSON.parse(JSON.stringify(arr))
arr.forEach(function(item, index) {
let isNumPresent = Object.values(item).includes(num)
if (isNumPresent) {
newArr.splice(index, 1);
}
})
return newArr;
}
console.log(removeValueFromObjectByValue(addedItems, 12));

Get the array index of duplicates

In a JavaScript array how can I get the index of duplicate strings?
Example:
MyArray = ["abc","def","abc"]; //----> return 0,2("abc");
Another example:
My Array = ["abc","def","abc","xyz","def","abc"]
//----> return 0,2,5("abc") and 1,4("def");
I have no idea how to do this.
Thanks in advance for your help!
Update 01/2022: It's not 2013 anymore, and many things have changed. I neither recommend modifying the prototype, nor is the approach in this answer the "best" as it requires several iterations over the array.
Here's an updated version of the original answer, retaining its spirit, as well as the original answer below.
function getDuplicates<T>(input: T[]): Map<T, number[]> {
return input.reduce((output, element, idx) => {
const recordedDuplicates = output.get(element);
if (recordedDuplicates) {
output.set(element, [...recordedDuplicates, idx]);
} else if (input.lastIndexOf(element) !== idx) {
output.set(element, [idx]);
}
return output;
}, new Map<T, number[]>());
}
Yet another approach:
Array.prototype.getDuplicates = function () {
var duplicates = {};
for (var i = 0; i < this.length; i++) {
if(duplicates.hasOwnProperty(this[i])) {
duplicates[this[i]].push(i);
} else if (this.lastIndexOf(this[i]) !== i) {
duplicates[this[i]] = [i];
}
}
return duplicates;
};
It returns an object where the keys are the duplicate entries and the values are an array with their indices, i.e.
["abc","def","abc"].getDuplicates() -> { "abc": [0, 2] }
Another less sophisticated approach:
Iterate over the whole array and keep track of the index of each element. For this we need a string -> positions map. An object is the usual data type to use for this. The keys are the elements of the array and the values are arrays of indexes/positions of each element in the array.
var map = {};
for (var i = 0; i < arr.length; i++) {
var element = arr[i]; // arr[i] is the element in the array at position i
// if we haven't seen the element yet,
// we have to create a new entry in the map
if (!map[element]) {
map[element] = [i];
}
else {
// otherwise append to the existing array
map[element].push(i);
}
// the whole if - else statement can be shortend to
// (map[element] || (map[element] = [])).push(i)
}
Now you can iterate over the map and remove all entries where the array value has a length of one. Those are elements that appear only once in an array:
for (var element in map) {
if (map[element].length === 1) {
delete map[element];
}
}
Now map contains a string -> positions mapping of all duplicate elements of the array. For example, if you array is ["abc","def","abc","xyz","def","abc"], then map is an object of the form
var map = {
'abc': [0,2,5],
'def': [1,4]
};
and you can process it further in any way you like.
Further reading:
Eloquent JavaScript - Data structures: Objects and Arrays
MDN - Working with objects
MDN - Predefined core objects, Array object
This covers finding the indices efficiently:
var inputArray = [1, 2, 3, 4, 5, 6, 6, 7, 8, 9];
var encounteredIndices = {};
for(var i = 0; i < inputArray.length; i++)
if (encounteredIndices[inputArray[i]])
console.log(i); // Or add to some array if you wish
else
encounteredIndices[inputArray[i]] = 1;

Returning key/value pair in javascript

I am writing a javascript program, whhich requires to store the original value of array of numbers and the doubled values in a key/value pair. I am beginner in javascript. Here is the program:
var Num=[2,10,30,50,100];
var obj = {};
function my_arr(N)
{
original_num = N
return original_num;
}
function doubling(N_doubled)
{
doubled_number = my_arr(N_doubled);
return doubled_number * 2;
}
for(var i=0; i< Num.length; i++)
{
var original_value = my_arr(Num[i]);
console.log(original_value);
var doubled_value = doubling(Num[i]);
obj = {original_value : doubled_value};
console.log(obj);
}
The program reads the content of an array in a function, then, in another function, doubles the value.
My program produces the following output:
2
{ original_value: 4 }
10
{ original_value: 20 }
30
{ original_value: 60 }
50
{ original_value: 100 }
100
{ original_value: 200 }
The output which I am looking for is like this:
{2:4, 10:20,30:60,50:100, 100:200}
What's the mistake I am doing?
Thanks.
Your goal is to enrich the obj map with new properties in order to get {2:4, 10:20,30:60,50:100, 100:200}. But instead of doing that you're replacing the value of the obj variable with an object having only one property.
Change
obj = {original_value : doubled_value};
to
obj[original_value] = doubled_value;
And then, at the end of the loop, just log
console.log(obj);
Here's the complete loop code :
for(var i=0; i< Num.length; i++) {
var original_value = my_arr(Num[i]);
var doubled_value = doubling(original_value);
obj[original_value] = doubled_value;
}
console.log(obj);
You can't use an expression as a label in an Object literal, it doesn't get evaluated. Instead, switch to bracket notation.
var original_value = my_arr(Num[i]),
doubled_value = doubling(Num[i]);
obj = {}; // remove this line if you don't want object to be reset each iteration
obj[original_value] = doubled_value;
Or:
//Original array
var Num=[2,10,30,50,100];
//Object with original array keys with key double values
var obj = myFunc(Num);
//Print object
console.log(obj);
function myFunc(arr)
{
var obj = {};
for (var i in arr) obj[arr[i]] = arr[i] * 2;
return obj;
}

javascript array with numeric index without undefineds

suppose I do..
var arr = Array();
var i = 3333;
arr[i] = "something";
if you do a stringify of this array it will return a string with a whole bunch of undefined numeric entries for those entries whose index is less than 3333...
is there a way to make javascript not do this?
I know that I can use an object {} but I would rather not since I want to do array operations such as shift() etc which are not available for objects
If you create an array per the OP, it only has one member with a property name of "333" and a length of 334 because length is always set to be at least one greater than the highest index. e.g.
var a = new Array(1000);
has a length of 1000 and no members,
var a = [];
var a[999] = 'foo';
has a length of 1000 and one member with a property name of "999".
The speedy way to only get defined members is to use for..in:
function myStringifyArray(a) {
var s = [];
var re = /^\d+$/;
for (var p in a) {
if (a.hasOwnProperty(p) && re.test(p)) {
s.push(a[p]);
}
}
return '' + s;
}
Note that the members may be returned out of order. If that is an issue, you can use a for loop instead, but it will be slower for very sparse arrays:
function myStringifyArray(a) {
var s = [];
var re = /^\d+$/;
for (var i=0, iLen=a.length; i<iLen; i++) {
if (a.hasOwnProperty(i)) {
s.push(a[i]);
}
}
return '' + s;
}
In some older browsers, iterating over the array actually created the missing members, but I don't think that's in issue in modern browsers.
Please test the above thoroughly.
The literal representation of an array has to have all the items of the array, otherwise the 3334th item would not end up at index 3333.
You can replace all undefined values in the array with something else that you want to use as empty items:
for (var i = 0; i < arr.length; i++) {
if (typeof arr[i] == 'undefined') arr[i] = '';
}
Another alternative would be to build your own stringify method, that would create assignments instead of an array literal. I.e. instead of a format like this:
[0,undefined,undefined,undefined,4,undefined,6,7,undefined,9]
your method would create something like:
(function(){
var result = [];
result[0] = 0;
result[4] = 4;
result[6] = 6;
result[7] = 7;
result[9] = 9;
return result;
}())
However, a format like that is of course not compatible with JSON, if that is what you need.

How to get object length [duplicate]

This question already has answers here:
Length of a JavaScript object
(43 answers)
Closed 3 years ago.
Is there any built-in function that can return the length of an object?
For example, I have a = { 'a':1,'b':2,'c':3 } which should return 3. If I use a.length it returns undefined.
It could be a simple loop function, but I'd like to know if there's a built-in function?
There is a related question (Length of a JSON object) - in the chosen answer the user advises to transform object into an array, which is not pretty comfortable for my task.
For browsers supporting Object.keys() you can simply do:
Object.keys(a).length;
Otherwise (notably in IE < 9), you can loop through the object yourself with a for (x in y) loop:
var count = 0;
var i;
for (i in a) {
if (a.hasOwnProperty(i)) {
count++;
}
}
The hasOwnProperty is there to make sure that you're only counting properties from the object literal, and not properties it "inherits" from its prototype.
This should do it:
Object.keys(a).length
However, Object.keys is not supported in IE8 and below, Opera and FF 3.6 and below.
Live demo: http://jsfiddle.net/simevidas/nN84h/
Can be done easily with $.map():
var len = $.map(a, function(n, i) { return i; }).length;
Have you taken a look at underscore.js (http://underscorejs.org/docs/underscore.html)? It's a utility library with a lot of useful methods. There is a collection size method, as well as a toArray method, which may get you what you need.
_.size({one : 1, two : 2, three : 3});
=> 3
Summarizing all together, here is a universal function (including ie8 support):
var objSize = function(obj) {
var count = 0;
if (typeof obj == "object") {
if (Object.keys) {
count = Object.keys(obj).length;
} else if (window._) {
count = _.keys(obj).length;
} else if (window.$) {
count = $.map(obj, function() { return 1; }).length;
} else {
for (var key in obj) if (obj.hasOwnProperty(key)) count++;
}
}
return count;
};
document.write(objSize({ a: 1, b: 2, c: 3 }));
// 3
In jQuery i've made it in a such way:
len = function(obj) {
var L=0;
$.each(obj, function(i, elem) {
L++;
});
return L;
}
So one does not have to find and replace the Object.keys method, another approach would be this code early in the execution of the script:
if(!Object.keys)
{
Object.keys = function(obj)
{
return $.map(obj, function(v, k)
{
return k;
});
};
}
Also can be done in this way:
Object.entries(obj).length
For example:
let obj = { a: 1, b: 2, };
console.log(Object.entries(obj).length); //=> 2
// Object.entries(obj) => [ [ 'a', 1 ], [ 'b', 2 ] ]
Here's a jQuery-ised function of Innuendo's answer, ready for use.
$.extend({
keyCount : function(o) {
if(typeof o == "object") {
var i, count = 0;
for(i in o) {
if(o.hasOwnProperty(i)) {
count++;
}
}
return count;
} else {
return false;
}
}
});
Can be called like this:
var cnt = $.keyCount({"foo" : "bar"}); //cnt = 1;
One more answer:
var j = '[{"uid":"1","name":"Bingo Boy", "profile_img":"funtimes.jpg"},{"uid":"2","name":"Johnny Apples", "profile_img":"badtime.jpg"}]';
obj = Object.keys(j).length;
console.log(obj)
For those coming here to find the item count of something that is already a jQuery object:
.length is what you are looking for:
Example:
len = $('#divID').length;
alert(len);
If you want to avoid new dependencies you could make your own smart objects. Of course only if you want to do more that just get it's size.
MyNeatObj = function (obj) {
var length = null;
this.size = function () {
if (length === null) {
length = 0;
for (var key in obj) length++;
}
return length;
}
}
var thingy = new MyNeatObj(originalObj);
thingy.size();
You might have an undefined property in the object.
If using the method of Object.keys(data).length is used those properties will also be counted.
You might want to filter them out out.
Object.keys(data).filter((v) => {return data[v] !== undefined}).length
You may use something like Lodash lib and _.toLength(object) should give you the length of your object
You could add another name:value pair of length, and increment/decrement it appropriately. This way, when you need to query the length, you don't have to iterate through the entire objects properties every time, and you don't have to rely on a specific browser or library. It all depends on your goal, of course.

Categories

Resources