Related
I need some help with iterating through array, I keep getting stuck or reinventing the wheel.
values = [
{ name: 'someName1' },
{ name: 'someName2' },
{ name: 'someName1' },
{ name: 'someName1' }
]
How could I check if there are two (or more) same name value in array? I do not need a counter, just setting some variable if array values are not unique. Have in mind that array length is dynamic, also array values.
Use array.prototype.map and array.prototype.some:
var values = [
{ name: 'someName1' },
{ name: 'someName2' },
{ name: 'someName4' },
{ name: 'someName2' }
];
var valueArr = values.map(function(item){ return item.name });
var isDuplicate = valueArr.some(function(item, idx){
return valueArr.indexOf(item) != idx
});
console.log(isDuplicate);
ECMA Script 6 Version
If you are in an environment which supports ECMA Script 6's Set, then you can use Array.prototype.some and a Set object, like this
let seen = new Set();
var hasDuplicates = values.some(function(currentObject) {
return seen.size === seen.add(currentObject.name).size;
});
Here, we insert each and every object's name into the Set and we check if the size before and after adding are the same. This works because Set.size returns a number based on unique data (set only adds entries if the data is unique). If/when you have duplicate names, the size won't increase (because the data won't be unique) which means that we would have already seen the current name and it will return true.
ECMA Script 5 Version
If you don't have Set support, then you can use a normal JavaScript object itself, like this
var seen = {};
var hasDuplicates = values.some(function(currentObject) {
if (seen.hasOwnProperty(currentObject.name)) {
// Current name is already seen
return true;
}
// Current name is being seen for the first time
return (seen[currentObject.name] = false);
});
The same can be written succinctly, like this
var seen = {};
var hasDuplicates = values.some(function (currentObject) {
return seen.hasOwnProperty(currentObject.name)
|| (seen[currentObject.name] = false);
});
Note: In both the cases, we use Array.prototype.some because it will short-circuit. The moment it gets a truthy value from the function, it will return true immediately, it will not process rest of the elements.
In TS and ES6 you can create a new Set with the property to be unique and compare it's size to the original array.
const values = [
{ name: 'someName1' },
{ name: 'someName2' },
{ name: 'someName3' },
{ name: 'someName1' }
]
const uniqueValues = new Set(values.map(v => v.name));
if (uniqueValues.size < values.length) {
console.log('duplicates found')
}
To know if simple array has duplicates we can compare first and last indexes of the same value:
The function:
var hasDupsSimple = function(array) {
return array.some(function(value) { // .some will break as soon as duplicate found (no need to itterate over all array)
return array.indexOf(value) !== array.lastIndexOf(value); // comparing first and last indexes of the same value
})
}
Tests:
hasDupsSimple([1,2,3,4,2,7])
// => true
hasDupsSimple([1,2,3,4,8,7])
// => false
hasDupsSimple([1,"hello",3,"bye","hello",7])
// => true
For an array of objects we need to convert the objects values to a simple array first:
Converting array of objects to the simple array with map:
var hasDupsObjects = function(array) {
return array.map(function(value) {
return value.suit + value.rank
}).some(function(value, index, array) {
return array.indexOf(value) !== array.lastIndexOf(value);
})
}
Tests:
var cardHand = [
{ "suit":"spades", "rank":"ten" },
{ "suit":"diamonds", "rank":"ace" },
{ "suit":"hearts", "rank":"ten" },
{ "suit":"clubs", "rank":"two" },
{ "suit":"spades", "rank":"three" },
]
hasDupsObjects(cardHand);
// => false
var cardHand2 = [
{ "suit":"spades", "rank":"ten" },
{ "suit":"diamonds", "rank":"ace" },
{ "suit":"hearts", "rank":"ten" },
{ "suit":"clubs", "rank":"two" },
{ "suit":"spades", "rank":"ten" },
]
hasDupsObjects(cardHand2);
// => true
if you are looking for a boolean, the quickest way would be
var values = [
{ name: 'someName1' },
{ name: 'someName2' },
{ name: 'someName1' },
{ name: 'someName1' }
]
// solution
var hasDuplicate = false;
values.map(v => v.name).sort().sort((a, b) => {
if (a === b) hasDuplicate = true
})
console.log('hasDuplicate', hasDuplicate)
const values = [
{ name: 'someName1' },
{ name: 'someName2' },
{ name: 'someName4' },
{ name: 'someName4' }
];
const foundDuplicateName = values.find((nnn, index) =>{
return values.find((x, ind)=> x.name === nnn.name && index !== ind )
})
console.log(foundDuplicateName)
Found the first one duplicate name
const values = [
{ name: 'someName1' },
{ name: 'someName2' },
{ name: 'someName4' },
{ name: 'someName4' }
];
const foundDuplicateName = values.find((nnn, index) =>{
return values.find((x, ind)=> x.name === nnn.name && index !== ind )
})
You just need one line of code.
var values = [
{ name: 'someName1' },
{ name: 'someName2' },
{ name: 'someName4' },
{ name: 'someName2' }
];
let hasDuplicates = values.map(v => v.name).length > new Set(values.map(v => v.name)).size ? true : false;
Try an simple loop:
var repeat = [], tmp, i = 0;
while(i < values.length){
repeat.indexOf(tmp = values[i++].name) > -1 ? values.pop(i--) : repeat.push(tmp)
}
Demo
With Underscore.js A few ways with Underscore can be done. Here is one of them. Checking if the array is already unique.
function isNameUnique(values){
return _.uniq(values, function(v){ return v.name }).length == values.length
}
With vanilla JavaScript
By checking if there is no recurring names in the array.
function isNameUnique(values){
var names = values.map(function(v){ return v.name });
return !names.some(function(v){
return names.filter(function(w){ return w==v }).length>1
});
}
//checking duplicate elements in an array
var arr=[1,3,4,6,8,9,1,3,4,7];
var hp=new Map();
console.log(arr.sort());
var freq=0;
for(var i=1;i<arr.length;i++){
// console.log(arr[i-1]+" "+arr[i]);
if(arr[i]==arr[i-1]){
freq++;
}
else{
hp.set(arr[i-1],freq+1);
freq=0;
}
}
console.log(hp);
You can use map to return just the name, and then use this forEach trick to check if it exists at least twice:
var areAnyDuplicates = false;
values.map(function(obj) {
return obj.name;
}).forEach(function (element, index, arr) {
if (arr.indexOf(element) !== index) {
areAnyDuplicates = true;
}
});
Fiddle
Adding updated es6 function to check for unique and duplicate values in array. This function is modular and can be reused throughout the code base. Thanks to all the post above.
/* checks for unique keynames in array */
const checkForUnique = (arrToCheck, keyName) => {
/* make set to remove duplicates and compare to */
const uniqueValues = [...new Set(arrToCheck.map(v => v[keyName]))];
if(arrToCheck.length !== uniqueValues.length){
console.log('NOT UNIQUE')
return false
}
return true
}
let arr = [{name:'joshua'},{name:'tony'},{name:'joshua'}]
/* call function with arr and key to check for */
let isUnique = checkForUnique(arr,'name')
checkDuplicate(arr, item) {
const uniqueValues = new Set(arr.map((v) => v[item]));
return uniqueValues.size < arr.length;
},
console.log(this.checkDuplicate(this.dutyExemptionBase, 'CI_ExemptionType')); // true || false
It is quite interesting to work with arrays
You can use new Set() method to find duplicate values!
let's assume you have an array of objects like this...
let myArray = [
{ id: 0, name: "Jhon" },
{ id: 1, name: "sara" },
{ id: 2, name: "pop" },
{ id: 3, name: "sara" }
]
const findUnique = new Set(myArray.map(x => {
return x.name
}))
if(findUnique.size < myArray.length){
console.log("duplicates found!")
}else{
console.log("Done!")
}
const duplicateValues = [{ name: "abc" }, { name: "bcv" }, { name: "abc" }];
const isContainDuplicate = (params) => {
const removedDuplicate = new Set(params.map((el) => el.name));
return params.length !== removedDuplicate.size;
};
const isDuplicate = isContainDuplicate(duplicateValues);
console.log("isDuplicate");
I want to iterate over a structure, push chosen nodes to an array and return all of them.
var structure = {
folder: getFolder(1, 'name1'),
children: [
{
folder: getFolder(2, 'name2'),
children: [
{
folder: getFolder(4, 'name2'),
children: []
}
]
},
{
folder: getFolder(3, 'name3'),
children: []
}
]
};
So for example, if folder node matches getFolder(x, 'name2'), I would get an array of two elements:
folder: getFolder(2, 'name2'),
children: [
{
folder: getFolder(4, 'name2'),
children: []
}
]
and
folder: getFolder(4, 'name2'),
children: []
Because both match the given criteria. The function I came up with is:
var searchAll = function (data, searchFor, results) {
results = results || [];
if (data[searchFor.type] != undefined &&
data[searchFor.type][searchFor.index].indexOf(searchFor.value) !== -1) {
return data;
}
if (data.children != null) {
var result = null;
for (var i = 0; result == null && i < data.children.length; i++) {
results.push(searchAll(data.children[i], searchFor, results));
}
}
return results;
};
searchAll(structure, {
type: 'folder',
index: 'name',
value: 'name2'
});
But it returns undefined. How should I do this?
The key to building up an array with recursion is the concat() method, which will properly return a copy of the array all the way up the recursion stack.
In the example below, objects that match your criteria get added in with push(), while child objects are searched through recursively and their results are concatenated to the result array. For simplicity I used the results of what your getFolder()function would return in the data:
var structure = {
folder: {id:1, name:'name1'}, //getFolder(1, 'name1'),
children: [{
folder: {id:2, name:'name2'}, //getFolder(2, 'name2'),
children: [{
folder: {id:4, name:'name2'}, //getFolder(4, 'name2'),
children: []
}]
}, {
folder: {id:3, name:'name3'}, //getFolder(3, 'name3'),
children: []
}]
};
function searchAll(object, criteria) {
var i, j, result = [];
for (i in object) {
if (i === criteria.type && object[i][criteria.index] === criteria.value) {
result.push(object);
} else if (i === 'children' && object[i].length > 0) {
for (j = 0; j < object[i].length; j++) {
result = result.concat(searchAll(object[i][j], criteria));
}
}
}
return result;
}
console.log(searchAll(structure, {type: 'folder', index: 'name', value: 'name2'}));
Edit: link to JSFiddle because it looks like the SO code snippet stops the recursion, the results should be correct (2 objects with the data you wanted)
https://jsfiddle.net/fswmxk7h/
The main issue is that you are bailing out and not appending to results when you find a match (return data;). This is a hopefully simpler and working version. You also have a problem that you are both passing 'results' to the recursion, and pushing the resulting array onto results, which isn't what you wanted. This is hopefully correct for the style you are going for (untested):
var searchAll = function (data, searchFor, results) {
results = results || [];
if (data[searchFor.type] &&
data[searchFor.type][searchFor.index].indexOf(searchFor.value) !== -1) {
results.push(data); // now carry on an recurse children
}
if (data.children) {
for (var i = 0; i < data.children.length; i++) {
// use results arg to avoid array creation on recursion:
searchAll(data.children[i], searchFor, results);
}
}
return results;
};
searchAll(structure, {
type: 'folder',
index: 'name',
value: 'name2'
});
I have 2 arrays of objects exclude and people, I want to create a new object by checking exclude properties against people properties and only adding objects in people that don't feature in exclude. So far my attempt is a little wild and wondering if someone can help make things a little better or offer a nicer solution?
Fiddle http://jsfiddle.net/kyllle/k02jw2j0/
JS
var exclude = [{
id: 1,
name: 'John'
}];
var peopleArr = [{
id: 1,
name: 'John'
}, {
id: 2,
name: 'James'
}, {
id: 3,
name: 'Simon'
}];
var myObj = [];
for (key in peopleArr) {
for (k in exclude) {
if (JSON.stringify(peopleArr[key]) != JSON.stringify(exclude[k])) {
console.log(peopleArr[key]);
myObj.push(peopleArr[key]);
}
}
}
console.log(myObj);
Under the assumption that exclude can have multiple items, I would use a combination of filter() and forEach() :
var newArray = peopleArr.filter(function(person) {
include = true;
exclude.forEach(function(exl) {
if (JSON.stringify(exl) == JSON.stringify(person)) {
include = false;
return;
}
})
if (include) return person;
})
forked fiddle -> http://jsfiddle.net/6c24rte8/
You repeat some JSON.stringify calls.
You can convert your arrays to JSON once, and then reuse it. Also, you can replace your push by Array.prototype.filter.
var excludeJson = exclude.map(JSON.stringify);
peopleArr = peopleArr.filter(function(x) {
return excludeJson.indexOf(JSON.stringify(x)) === -1;
});
Here is the working snippet:
var exclude = [{
id: 1,
name: 'John'
}];
var peopleArr = [{
id: 1,
name: 'John'
}, {
id: 2,
name: 'James'
}, {
id: 3,
name: 'Simon'
}];
var excludeJson = exclude.map(JSON.stringify);
peopleArr = peopleArr.filter(function(x) {
return excludeJson.indexOf(JSON.stringify(x)) === -1;
});
document.body.innerText = JSON.stringify(peopleArr);
This can be achieved with .filter and .findIndex
var myObj = peopleArr.filter(function(person){
var idx = exclude.findIndex(function(exc) { return person.id == exc.id && person.name == exc.name; });
return idx == -1; // means current person not found in the exclude list
});
I have explicitly compared the actual properties back to the original, there is nothing particularly wrong with your original way of comparing the stringified version (JSON.stringify(e) == JSON.stringify(x) could be used in my example)
I need some help with iterating through array, I keep getting stuck or reinventing the wheel.
values = [
{ name: 'someName1' },
{ name: 'someName2' },
{ name: 'someName1' },
{ name: 'someName1' }
]
How could I check if there are two (or more) same name value in array? I do not need a counter, just setting some variable if array values are not unique. Have in mind that array length is dynamic, also array values.
Use array.prototype.map and array.prototype.some:
var values = [
{ name: 'someName1' },
{ name: 'someName2' },
{ name: 'someName4' },
{ name: 'someName2' }
];
var valueArr = values.map(function(item){ return item.name });
var isDuplicate = valueArr.some(function(item, idx){
return valueArr.indexOf(item) != idx
});
console.log(isDuplicate);
ECMA Script 6 Version
If you are in an environment which supports ECMA Script 6's Set, then you can use Array.prototype.some and a Set object, like this
let seen = new Set();
var hasDuplicates = values.some(function(currentObject) {
return seen.size === seen.add(currentObject.name).size;
});
Here, we insert each and every object's name into the Set and we check if the size before and after adding are the same. This works because Set.size returns a number based on unique data (set only adds entries if the data is unique). If/when you have duplicate names, the size won't increase (because the data won't be unique) which means that we would have already seen the current name and it will return true.
ECMA Script 5 Version
If you don't have Set support, then you can use a normal JavaScript object itself, like this
var seen = {};
var hasDuplicates = values.some(function(currentObject) {
if (seen.hasOwnProperty(currentObject.name)) {
// Current name is already seen
return true;
}
// Current name is being seen for the first time
return (seen[currentObject.name] = false);
});
The same can be written succinctly, like this
var seen = {};
var hasDuplicates = values.some(function (currentObject) {
return seen.hasOwnProperty(currentObject.name)
|| (seen[currentObject.name] = false);
});
Note: In both the cases, we use Array.prototype.some because it will short-circuit. The moment it gets a truthy value from the function, it will return true immediately, it will not process rest of the elements.
In TS and ES6 you can create a new Set with the property to be unique and compare it's size to the original array.
const values = [
{ name: 'someName1' },
{ name: 'someName2' },
{ name: 'someName3' },
{ name: 'someName1' }
]
const uniqueValues = new Set(values.map(v => v.name));
if (uniqueValues.size < values.length) {
console.log('duplicates found')
}
To know if simple array has duplicates we can compare first and last indexes of the same value:
The function:
var hasDupsSimple = function(array) {
return array.some(function(value) { // .some will break as soon as duplicate found (no need to itterate over all array)
return array.indexOf(value) !== array.lastIndexOf(value); // comparing first and last indexes of the same value
})
}
Tests:
hasDupsSimple([1,2,3,4,2,7])
// => true
hasDupsSimple([1,2,3,4,8,7])
// => false
hasDupsSimple([1,"hello",3,"bye","hello",7])
// => true
For an array of objects we need to convert the objects values to a simple array first:
Converting array of objects to the simple array with map:
var hasDupsObjects = function(array) {
return array.map(function(value) {
return value.suit + value.rank
}).some(function(value, index, array) {
return array.indexOf(value) !== array.lastIndexOf(value);
})
}
Tests:
var cardHand = [
{ "suit":"spades", "rank":"ten" },
{ "suit":"diamonds", "rank":"ace" },
{ "suit":"hearts", "rank":"ten" },
{ "suit":"clubs", "rank":"two" },
{ "suit":"spades", "rank":"three" },
]
hasDupsObjects(cardHand);
// => false
var cardHand2 = [
{ "suit":"spades", "rank":"ten" },
{ "suit":"diamonds", "rank":"ace" },
{ "suit":"hearts", "rank":"ten" },
{ "suit":"clubs", "rank":"two" },
{ "suit":"spades", "rank":"ten" },
]
hasDupsObjects(cardHand2);
// => true
if you are looking for a boolean, the quickest way would be
var values = [
{ name: 'someName1' },
{ name: 'someName2' },
{ name: 'someName1' },
{ name: 'someName1' }
]
// solution
var hasDuplicate = false;
values.map(v => v.name).sort().sort((a, b) => {
if (a === b) hasDuplicate = true
})
console.log('hasDuplicate', hasDuplicate)
const values = [
{ name: 'someName1' },
{ name: 'someName2' },
{ name: 'someName4' },
{ name: 'someName4' }
];
const foundDuplicateName = values.find((nnn, index) =>{
return values.find((x, ind)=> x.name === nnn.name && index !== ind )
})
console.log(foundDuplicateName)
Found the first one duplicate name
const values = [
{ name: 'someName1' },
{ name: 'someName2' },
{ name: 'someName4' },
{ name: 'someName4' }
];
const foundDuplicateName = values.find((nnn, index) =>{
return values.find((x, ind)=> x.name === nnn.name && index !== ind )
})
You just need one line of code.
var values = [
{ name: 'someName1' },
{ name: 'someName2' },
{ name: 'someName4' },
{ name: 'someName2' }
];
let hasDuplicates = values.map(v => v.name).length > new Set(values.map(v => v.name)).size ? true : false;
Try an simple loop:
var repeat = [], tmp, i = 0;
while(i < values.length){
repeat.indexOf(tmp = values[i++].name) > -1 ? values.pop(i--) : repeat.push(tmp)
}
Demo
With Underscore.js A few ways with Underscore can be done. Here is one of them. Checking if the array is already unique.
function isNameUnique(values){
return _.uniq(values, function(v){ return v.name }).length == values.length
}
With vanilla JavaScript
By checking if there is no recurring names in the array.
function isNameUnique(values){
var names = values.map(function(v){ return v.name });
return !names.some(function(v){
return names.filter(function(w){ return w==v }).length>1
});
}
//checking duplicate elements in an array
var arr=[1,3,4,6,8,9,1,3,4,7];
var hp=new Map();
console.log(arr.sort());
var freq=0;
for(var i=1;i<arr.length;i++){
// console.log(arr[i-1]+" "+arr[i]);
if(arr[i]==arr[i-1]){
freq++;
}
else{
hp.set(arr[i-1],freq+1);
freq=0;
}
}
console.log(hp);
You can use map to return just the name, and then use this forEach trick to check if it exists at least twice:
var areAnyDuplicates = false;
values.map(function(obj) {
return obj.name;
}).forEach(function (element, index, arr) {
if (arr.indexOf(element) !== index) {
areAnyDuplicates = true;
}
});
Fiddle
Adding updated es6 function to check for unique and duplicate values in array. This function is modular and can be reused throughout the code base. Thanks to all the post above.
/* checks for unique keynames in array */
const checkForUnique = (arrToCheck, keyName) => {
/* make set to remove duplicates and compare to */
const uniqueValues = [...new Set(arrToCheck.map(v => v[keyName]))];
if(arrToCheck.length !== uniqueValues.length){
console.log('NOT UNIQUE')
return false
}
return true
}
let arr = [{name:'joshua'},{name:'tony'},{name:'joshua'}]
/* call function with arr and key to check for */
let isUnique = checkForUnique(arr,'name')
checkDuplicate(arr, item) {
const uniqueValues = new Set(arr.map((v) => v[item]));
return uniqueValues.size < arr.length;
},
console.log(this.checkDuplicate(this.dutyExemptionBase, 'CI_ExemptionType')); // true || false
It is quite interesting to work with arrays
You can use new Set() method to find duplicate values!
let's assume you have an array of objects like this...
let myArray = [
{ id: 0, name: "Jhon" },
{ id: 1, name: "sara" },
{ id: 2, name: "pop" },
{ id: 3, name: "sara" }
]
const findUnique = new Set(myArray.map(x => {
return x.name
}))
if(findUnique.size < myArray.length){
console.log("duplicates found!")
}else{
console.log("Done!")
}
const duplicateValues = [{ name: "abc" }, { name: "bcv" }, { name: "abc" }];
const isContainDuplicate = (params) => {
const removedDuplicate = new Set(params.map((el) => el.name));
return params.length !== removedDuplicate.size;
};
const isDuplicate = isContainDuplicate(duplicateValues);
console.log("isDuplicate");
pretty simple question, can't quite fig. it out.
I have 2 js array's that I need to combine into a new array, based on sub_key.
var items = [
Object {
OBJECTID=1,
Name="COMMAND B",
ID="AR0xx",
sub_key="1000"
},
Object {
OBJECTID=2,
Name="95TH PCT",
ID="AR0xx",
sub_key="1001"
},
Object {
OBJECTID=379,
Name="dummy4",
ID="AR0xx",
sub_key="9999"
}
];
var subitems = [
Object {
OBJECTID=787,
ID="AR0xx",
sub_key=1000,
Long_Name = foo
},
Object {
OBJECTID=789,
ID="AR0xx",
sub_key=1001,
Long_Name = "bar"
},
Object {
OBJECTID=1,
ID="AR0xx",
sub_key=1001,
Long_Name="baz"
},
Object {
OBJECTID=788,
ID="AR0xx",
sub_key=1001,
Long_Name="buzzz"
}
];
I'd like to create an array like so, which just combines the above 2, based on sub_key
var data = [
COMMAND B=["foo"],
95TH PCT=["bar","baz","buzz"]
dummy4=[]
];
Here's what I tried but it doesn't work... i think i'm close?? thanks for any help!
data = [];
for (var key in items){
var o = items[key];
//data.push(o.Name);
for (var subkey in subitems){
subo = subitems[subkey];
if (o.sub_key == subo.sub_key){
data[o.Name].push(subo.Long_Name)
}
}
}
Cleaning up your script, here is what you are trying to do. It craetes an array of objects using the Name from items and matching sub_key from sub_items.
var items = [
{ OBJECTID: 1,
Name: 'COMMAND B',
ID: 'AR0xx',
sub_key: '1000'
},
{ OBJECTID: 2,
Name: '95TH PCT',
ID: 'AR0xx',
sub_key: '1001'
},
{ OBJECTID: 379,
Name: 'dummy4',
ID: 'AR0xx',
sub_key: '9999'
}
];
var subitems = [
{ BJECTID: 787,
ID: 'AR0xx',
sub_key: '1000',
Long_Name: 'foo'
},
{ OBJECTID: '789',
ID: 'AR0xx',
sub_key: '1001',
Long_Name: 'bar'
},
{ OBJECTID: '1',
ID: 'AR0xx',
sub_key: 1001,
Long_Name: 'baz'
},
{ OBJECTID: '788',
ID: 'AR0xx',
sub_key: '1001',
Long_Name: 'buzzz'
}
];
var j = subitems.length;
var result = {};
var p;
var sub_key;
var obj;
for (var i=0, iLen = items.length; i<iLen; i++) {
p = items[i].Name;
result[p] = [];
sub_key = items[i].sub_key;
for (var j=0, jLen=subitems.length; j<jLen; j++) {
if (subitems[j].sub_key == sub_key) {
result[p].push(subitems[j].Long_Name);
}
}
}
alert(result['95TH PCT']); // bar, baz, buzz
Edit
Return a single object rather than an array of objects, which I think is what is required.
var newarray = items.slice(0); // make a copy
addloop: for (var i=0; i<subitems.length; i++) {
for (var j=0; j<newarray.length; j++)
if (subitems[i].sub_key == newarray[j].sub_key)
continue addloop;
newarray.push(subitems[i]);
}
should work. Another solution:
Array.prototype.combine = function(a, test) {
if (typeof test == "function") {
for (var i=0; i<a.length; i++)
if (! this.some(test.bind(null, a[i])))
this.push(a[i]);
} else {
for (var i=0; i<a.length; i++)
if (this.indexOf(a[i]) == -1)
this.push(a[i]);
}
return this;
};
var newarray = items.slice(0).combine(subitems, function(a, b) {
return a.sub_key == b.sub_key;
});
I wrote this on the train but didn't get to post it, and it looks like a couple of other people posted good answers since, but it might still be helpful so I'll post it anyways
I had a few different things to note:
var items = [
Object {
OBJECTID=1,
Name="COMMAND B",
ID="AR0xx",
sub_key="1000"
},
...
You don't need the word Object here, you can just write { ... } and JS knows it's an object.
Within an object, you need : instead of =
It's not required, but putting the key in quotes is good practice because some keys won't work otherwise.
So it should look like this:
var items = [
{
"OBJECTID": 1,
"Name": "COMMAND B",
"ID": "AR0xx",
"sub_key": "1000"
},
...
Next up, I'm not completely clear on what you're doing with your data array in the second block, but it looks like you're overriding it with an empty array in the third block.
Also, I think you may be confusing Objects and Arrays somewhat. http://nfriedly.com/techblog/2009/06/advanced-javascript-objects-arrays-and-array-like-objects/ has a good overview of the differences, but here's some key points:
Array is a subclass of Object
Array values always have numeric indexes, not string keys
push() is a method of Array not Object
Next up, your loop. for .. in style loops do work on arrays, but they're not generally recommended because they can also hit keys that were added to the underlying Object. forEach is my favorite but it's not always available in older browsers without a library such as underscore.js.
for(var i=0, len=MyArray.length; i<len; i++) {...} is the other option that you'll see very commonly because it covers all of the array items but does not have the possibility of hitting the underlying object.
But, since Bergi and RobG both have good loops, I'll stop here.