Add item to array by key in JavaScript - javascript

I need to group item having same name property and increase their number. I try to assign to new array and check existed item by key. It works fine when I use this solution in PHP, but in JavaScript it doesn't.
I have searched some similar questions, but I don't know why it doesn't work.
var orgArr = [
{name: 'abc', number: 3},
{name: 'xyz', number: 2},
{name: 'abc', number: 5}
];
var result = []; //work if result = {};
for (var i = 0; i < orgArr.length; i++) {
if (!result[orgArr[i].name]) {
result[orgArr[i].name] = orgArr[i]; //assign new
} else {
result[orgArr[i].name].number += orgArr[i].number; //increase number if name exist in result array
}
}
alert(JSON.stringify(result)); //expect array 2 item but it's empty array
console.log(result); //Will have result 2 item when I view console window

var orgArr = [
{name: 'abc', number: 3},
{name: 'xyz', number: 2},
{name: 'abc', number: 5}
];
var result = []; //work if result = {};
var tempArray = []; // used to store unique name to prevent complex loop
orgArr.forEach(function(item){
if($.inArray(item.name, tempArray)< 0){// unique name
result.push(item);
tempArray.push(item.name);
}
else{
var indexNew = $.inArray(item.name, tempArray);
result[indexNew].number += item.number;
}
});
alert(JSON.stringify(result)); //expect array 2 item but it's empty array
console.log(result); //Will have result 2 item when I view console window
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

E/ My previous answer was incorrect.
Well.. yes...
[] designates an array. An array holds everything by integer values. You're trying to feed it a string value (orgArr[x].name) and since its just an array, it discards it as a bad call.
{} is an object. Objects can have string indexes.
var result = []; //work if result = {};
Why can't result be {}?

if you want it to work, make result = {} not []
an array is not a key value store. It still will take key values, and will store them on the array object. But when stringify encounters your array, it determines it is an array and then trys to iterate the array, and your array appears empty. so you get nothing in your output.

You get empty array it's because by default JSON.stringify failed to convert your array to json string.
By default JSON.stringify converts int-based index array to json string but you are using orgArr[i].name which is a string as array index that the cause alert() show empty array.
Can you explain why would you want to convert json array to an array with string index. It's always better to use json array if you want a string as key/index.
For more information about JSON.stringify

Related

Grabbing names of object of out a JSON object in javascript and storing it in an String Array

So the issues that I am currently having is a string manipulation logic issue. My goal is to store the names of JSON objects in a string array. So it will be easier to access the data later on. But the current issue that I am running into is that the output is nothing that I want or understand of how it is getting it. Currently I am looking for the quotes between the object names and returning it to a string using str.substring, and storing it in an index of newArr. The output equals in 4th code snippet. I have also tried putting an underscore before and after the object name in the JSON object, then searching for the underscore. From my testing this will only work with the first name, which will return "foo" in index 0, while the rest of the indexes equal to '"_'. I know there is something wrong with my logic in the function, but I can not pinpoint what it is. Any help would be appreciated
This is the function that is being ran.
exports.jsonObjectToArray = function (objectToTurn){
var oldArr = JSON.stringify(objectToTurn).split(","),
firstIndex,
secondIndex,
newArr = [];
for(let i = 0; i < oldArr.length; i ++){
firstIndex = oldArr[i].indexOf("\"");
secondIndex = oldArr[i].indexOf(firstIndex, "\"");
newArr[i] = oldArr[i].substring(firstIndex, secondIndex);
}
return newArr;
}
When the function is ran oldArr will equal to this value.
[ '{"foo":"',
'"bar":"0"',
'"Mar":"0"',
'"Car":"0"}'
]
And my goal is to return this. Which will be stored in newArr.
[
"foo",
"bar",
"Mar",
"Car"
]
But after the function runs this is what I get returned.
[
'{"',
'bar":"0',
'Mar":"0',
'Car":"0'
]
To get the keys from an object, simply use Object.keys().
Quick example:
var obj = {
foo: '1',
bar: '2',
car: '3'
};
console.log(Object.keys(obj)); // ==> (3) ["foo", "bar", "car"]
let arr = [ '{"foo":"',
'"bar":"0"',
'"Mar":"0"',
'"Car":"0"}'
]
let arr1 = arr.map(el => el.split('"')[1])

pushing strings into an object

I have an array of objects and an array of string and I am tying to combine the two in sequence meaning I would like to first item on the array to be stored only in the first object, second item of the array only in the second object, ect. Something like the following.
var objects = [ obj1, obj2, obj3];
var strings = ["123", "456", "789"];
//Result
var results = [
{
"obj1": {
number: "123"
},
{
"obj2": {
number: "456"
},
{
"obj2": {
number: "789"
}
];
I have been trying to do this with a push and a for loop but I seem to end up with each object containing all three strings.
Its easy:-
for (var i = 0; i < objects.length; i++) {// start loop for getting values one by one from object array
objects[i].number = strings[i]; // assign string values to object array values
}
Matched object and string share the same array index:
for (var i = 0; i < objects.length; i++) {
objects[i].number = strings[i];
}
Or you could do this using the map function:
var results = objects.map(function (value, index) {
return Object.assign({}, value, { number: strings[index] });
});
The other answers are good I just wanted to give you another way. This way you also do not modify the existing objects array
In case you don't know Object.assign add to the first argument (in our case the empty object {}) all the properties from the other object arguments. You can read more about it here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
Also, you can learn here about the map function: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

Array of Objects (JavaScript) merge and add properties with same key

I have an array of objects like so:
array = [{item_name: "necklace", quantity: "2"},
{item_name: "necklace", quantity: "4"},
{item_name: "bracelet", quantity: "5"}];
I would like to merge these objects in the array to end up with an array that looks like this:
array = [{item_name: "necklace", quantity: "6"},
{item_name: "bracelet", quantity: "5"}];
I'm unsure how to begin to tackle this. I have tried concat and merge but these override the values. Do I need to map?
Any help would be greatly appreciated!
You can just simply loop over the array and push the values into a new array, checking first to see if the item_name is already in there.
An easier way to check if the object is already in the new array is to create an object with the item_name and its position in the new array. Otherwise, you'd need to loop over the new array each time to check.
Try this:
function merge_data(array){
var new_array = [],
item_map = {};
// Loop over the array
array.forEach(function(v){
var item = v.item_name;
// The object is not already in the new array
if(item_map[item] === undefined){
// Push the object and save its index
item_map[item] = new_array.length;
// WARNING: This pushes a *reference* to `v` into the new array
// which means when I update `new_array[pos]`, it'll also update
// this object in the *original* array
//new_array.push(v);
new_array.push({
item_name: item,
quantity: v.quantity
});
}
// The object is already in the new array
else{
// Get its index and update the quantity
var pos = item_map[item],
// quantity is a string, we need to make it into an int
quantity = parseInt(new_array[pos].quantity, 10);
new_array[pos].quantity = quantity + parseInt(v.quantity, 10);
}
});
return new_array;
}
// Now `array` will have the merged data
array = merge_data(array);
console.log(array);

search value of index in indexed array javascript

Let's take an indexed (associative) array as shown below
var gh = { pop: 'apple', jim: 'orange', john: 'ball', sim: 'oran' }
How can I search this array to find the indexes where the value is like 'ora'?
Example:
If I given input ora I have to get indexes jim and sim as output.
So you're needing the keys of Object whose value matches certain pattern. You could use [].filter on Object.keys(gh) which returns an Array of keys for the Object passed in.
var str = "ora", gh = { pop: 'apple', jim: 'orange', john: 'ball', sim: 'oran' };
var output = Object.keys(gh).filter(function(key){
return gh[key].indexOf(str) == 0; // condition
});
Use the condition gh[key].indexOf(str) > -1 if str can appear anywhere in the String not just at the start. You could see the contents of output Array by logging it
console.log(output);
If you want to get them as Array of {key:value} as you've stated in the comments, you could do
var result = output.map(function(k){
var obj = {};
obj[k] = gh[k];
return obj;
});

javascript datastructure question

I have an array:
myArray = [];
To which I am adding objects:
data = [];
myArray.push( {
elem1: ...,
elem2: data.push(...);
} );
So, elem2 in the object contains an array. How can I, given myArray add new elements to the array in elem2? I tried the following:
myArray[idx].elem2.push("new data");
But got an error saying that elem2.push() is not a method.
The issue line is:
elem2: data.push(...)
data is an array. The push method for arrays does not return the array, it returns the length of the array once the item has been added.
So if you have:
var data = [];
var moreData = data.push(1);
moreData will actually equal 1.
Since the value of elem2 is actually an integer, you are then calling push on that integer. That's where you are getting the error.
The .push() function does not return the array, so that line that tries to set "elem2", well it isn't doing that.
I tried the same and works, look the code:
var a = [];
a.push({
a: []
});
a[0].a.push("a");
alert(a[0].a[0]); // return 'a'
in your array you must add another array, not the array.push(), because it will return the position that elements was inserted.

Categories

Resources